@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.
- package/CHANGELOG.md +66 -0
- package/LICENSE +202 -0
- package/README.md +24 -0
- package/bin/cli.js +3 -0
- package/cli.d.ts +1 -0
- package/cli.js +4 -0
- package/config.d.ts +2 -0
- package/config.js +5 -0
- package/dist/app/App/index.android.d.ts +2 -0
- package/dist/app/App/index.ios.d.ts +6 -0
- package/dist/app/Granite.d.ts +60 -0
- package/dist/app/index.d.ts +2 -0
- package/dist/app/registerPage.d.ts +20 -0
- package/dist/async-bridges.d.ts +2 -0
- package/dist/constant-bridges.d.ts +1 -0
- package/dist/dev-entrypoint/index.d.ts +2 -0
- package/dist/event/abstract.d.ts +42 -0
- package/dist/event/index.d.ts +2 -0
- package/dist/event/useGraniteEvent.d.ts +14 -0
- package/dist/impression-area/ImpressionArea.d.ts +231 -0
- package/dist/impression-area/index.d.ts +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/initial-props/InitialProps.d.ts +127 -0
- package/dist/initial-props/index.d.ts +1 -0
- package/dist/intersection-observer/IOContext.d.ts +10 -0
- package/dist/intersection-observer/IOFlatList.d.ts +55 -0
- package/dist/intersection-observer/IOManager.d.ts +24 -0
- package/dist/intersection-observer/IOScrollView.d.ts +59 -0
- package/dist/intersection-observer/InView.d.ts +107 -0
- package/dist/intersection-observer/IntersectionObserver.d.ts +67 -0
- package/dist/intersection-observer/index.d.ts +8 -0
- package/dist/intersection-observer/withIO.d.ts +20 -0
- package/dist/jest/index.d.ts +1 -0
- package/dist/jest/index.js +32 -0
- package/dist/keyboard/KeyboardAboveView.d.ts +40 -0
- package/dist/keyboard/index.d.ts +1 -0
- package/dist/keyboard/useKeyboardAnimatedHeight.d.ts +20 -0
- package/dist/native-event-emitter/eventEmitters/index.d.ts +2 -0
- package/dist/native-event-emitter/eventEmitters/types.d.ts +4 -0
- package/dist/native-event-emitter/eventEmitters/visibilityChanged.d.ts +10 -0
- package/dist/native-event-emitter/index.d.ts +1 -0
- package/dist/native-event-emitter/nativeEventEmitter.d.ts +15 -0
- package/dist/native-modules/core/GraniteCoreModule.d.ts +8 -0
- package/dist/native-modules/index.d.ts +3 -0
- package/dist/native-modules/natives/GraniteModule.d.ts +7 -0
- package/dist/native-modules/natives/closeView.d.ts +21 -0
- package/dist/native-modules/natives/getSchemeUri.d.ts +23 -0
- package/dist/native-modules/natives/index.d.ts +3 -0
- package/dist/native-modules/natives/openURL.d.ts +36 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/useWaitForReturnNavigator.d.ts +39 -0
- package/dist/rn-polyfills/index.d.ts +1 -0
- package/dist/rn-polyfills/symbol-asynciterator/index.d.ts +9 -0
- package/dist/rn-polyfills/url/index.d.ts +1 -0
- package/dist/router/Router.d.ts +59 -0
- package/dist/router/components/BackButton.d.ts +7 -0
- package/dist/router/components/CanGoBackGuard.d.ts +6 -0
- package/dist/router/components/RouterBackButton.d.ts +9 -0
- package/dist/router/components/StackNavigator.d.ts +54 -0
- package/dist/router/constants.d.ts +2 -0
- package/dist/router/createRoute.d.ts +39 -0
- package/dist/router/createRoute.test-d.d.ts +9 -0
- package/dist/router/hooks/useInitialRouteName.d.ts +1 -0
- package/dist/router/hooks/useIsInitialScreen.d.ts +1 -0
- package/dist/router/hooks/useRouterControls.d.ts +11 -0
- package/dist/router/index.d.ts +3 -0
- package/dist/router/types/RequireContext.d.ts +7 -0
- package/dist/router/types/RouteScreen.d.ts +16 -0
- package/dist/router/types/Screen.d.ts +23 -0
- package/dist/router/types/index.d.ts +3 -0
- package/dist/router/types/screen-option.d.ts +4 -0
- package/dist/router/utils/createParentRouteScreenMap.d.ts +8 -0
- package/dist/router/utils/defaultParserParams.d.ts +9 -0
- package/dist/router/utils/index.d.ts +2 -0
- package/dist/router/utils/matchers.d.ts +2 -0
- package/dist/router/utils/mergeParentLayoutScreen.d.ts +18 -0
- package/dist/router/utils/path.d.ts +53 -0
- package/dist/router/utils/screen.d.ts +53 -0
- package/dist/scroll-view-inertial-background/ScrollViewInertialBackground.d.ts +49 -0
- package/dist/scroll-view-inertial-background/index.d.ts +1 -0
- package/dist/types/global.d.ts +18 -0
- package/dist/use-back-event/index.d.ts +1 -0
- package/dist/use-back-event/useBackEvent.d.ts +135 -0
- package/dist/utils/noop.d.ts +1 -0
- package/dist/utils/usePreservedCallback.d.ts +1 -0
- package/dist/visibility/VisibilityProvider.d.ts +27 -0
- package/dist/visibility/index.d.ts +6 -0
- package/dist/visibility/react-navigation/index.d.ts +2 -0
- package/dist/visibility/react-navigation/useIsFocusedSafely.d.ts +20 -0
- package/dist/visibility/react-navigation/useNavigationSafely.d.ts +19 -0
- package/dist/visibility/useIsAppForeground.d.ts +39 -0
- package/dist/visibility/useVisibility.d.ts +35 -0
- package/dist/visibility/useVisibilityChange.d.ts +51 -0
- package/dist/visibility/useVisibilityChanged.d.ts +41 -0
- package/dist/visibility/utils/usePrevious.d.ts +15 -0
- package/jest.d.ts +1 -0
- package/package.json +92 -0
- package/presets.d.ts +1 -0
- package/src/app/App/index.android.tsx +6 -0
- package/src/app/App/index.d.ts +6 -0
- package/src/app/App/index.ios.tsx +13 -0
- package/src/app/Granite.tsx +130 -0
- package/src/app/index.ts +2 -0
- package/src/app/registerPage.ts +29 -0
- package/src/async-bridges.ts +2 -0
- package/src/constant-bridges.ts +1 -0
- package/src/dev-entrypoint/index.tsx +21 -0
- package/src/event/abstract.ts +130 -0
- package/src/event/index.ts +2 -0
- package/src/event/useGraniteEvent.ts +34 -0
- package/src/impression-area/ImpressionArea.tsx +341 -0
- package/src/impression-area/index.ts +1 -0
- package/src/index.ts +19 -0
- package/src/initial-props/InitialProps.ts +144 -0
- package/src/initial-props/index.ts +1 -0
- package/src/intersection-observer/IOContext.ts +16 -0
- package/src/intersection-observer/IOFlatList.ts +72 -0
- package/src/intersection-observer/IOManager.ts +73 -0
- package/src/intersection-observer/IOScrollView.ts +69 -0
- package/src/intersection-observer/InView.tsx +205 -0
- package/src/intersection-observer/IntersectionObserver.ts +212 -0
- package/src/intersection-observer/index.ts +24 -0
- package/src/intersection-observer/withIO.tsx +151 -0
- package/src/jest/index.ts +1 -0
- package/src/keyboard/KeyboardAboveView.tsx +62 -0
- package/src/keyboard/index.ts +1 -0
- package/src/keyboard/useKeyboardAnimatedHeight.tsx +81 -0
- package/src/native-event-emitter/eventEmitters/index.ts +3 -0
- package/src/native-event-emitter/eventEmitters/types.ts +4 -0
- package/src/native-event-emitter/eventEmitters/visibilityChanged.ts +11 -0
- package/src/native-event-emitter/index.ts +1 -0
- package/src/native-event-emitter/nativeEventEmitter.ts +18 -0
- package/src/native-modules/core/GraniteCoreModule.ts +9 -0
- package/src/native-modules/index.ts +3 -0
- package/src/native-modules/natives/GraniteModule.ts +8 -0
- package/src/native-modules/natives/closeView.ts +25 -0
- package/src/native-modules/natives/getSchemeUri.ts +27 -0
- package/src/native-modules/natives/index.ts +3 -0
- package/src/native-modules/natives/openURL.ts +40 -0
- package/src/react/index.ts +1 -0
- package/src/react/useWaitForReturnNavigator.ts +75 -0
- package/src/rn-polyfills/index.ts +7 -0
- package/src/rn-polyfills/symbol-asynciterator/index.ts +15 -0
- package/src/rn-polyfills/url/index.ts +1 -0
- package/src/router/Router.tsx +164 -0
- package/src/router/components/BackButton.tsx +58 -0
- package/src/router/components/CanGoBackGuard.tsx +31 -0
- package/src/router/components/RouterBackButton.tsx +32 -0
- package/src/router/components/StackNavigator.tsx +12 -0
- package/src/router/constants.ts +3 -0
- package/src/router/createRoute.test-d.ts +52 -0
- package/src/router/createRoute.ts +161 -0
- package/src/router/hooks/useInitialRouteName.tsx +22 -0
- package/src/router/hooks/useIsInitialScreen.ts +7 -0
- package/src/router/hooks/useRouterControls.tsx +72 -0
- package/src/router/index.ts +3 -0
- package/src/router/types/RequireContext.ts +7 -0
- package/src/router/types/RouteScreen.ts +17 -0
- package/src/router/types/Screen.tsx +24 -0
- package/src/router/types/index.ts +3 -0
- package/src/router/types/screen-option.ts +23 -0
- package/src/router/utils/createParentRouteScreenMap.spec.ts +166 -0
- package/src/router/utils/createParentRouteScreenMap.ts +136 -0
- package/src/router/utils/defaultParserParams.spec.ts +46 -0
- package/src/router/utils/defaultParserParams.ts +19 -0
- package/src/router/utils/index.ts +2 -0
- package/src/router/utils/matchers.ts +5 -0
- package/src/router/utils/mergeParentLayoutScreen.spec.tsx +112 -0
- package/src/router/utils/mergeParentLayoutScreen.tsx +43 -0
- package/src/router/utils/path.spec.ts +135 -0
- package/src/router/utils/path.ts +105 -0
- package/src/router/utils/screen.tsx +111 -0
- package/src/scroll-view-inertial-background/ScrollViewInertialBackground.tsx +99 -0
- package/src/scroll-view-inertial-background/index.ts +1 -0
- package/src/types/global.ts +31 -0
- package/src/use-back-event/index.ts +1 -0
- package/src/use-back-event/useBackEvent.tsx +260 -0
- package/src/utils/noop.ts +1 -0
- package/src/utils/usePreservedCallback.ts +16 -0
- package/src/visibility/VisibilityProvider.tsx +36 -0
- package/src/visibility/index.ts +6 -0
- package/src/visibility/react-navigation/index.ts +2 -0
- package/src/visibility/react-navigation/useIsFocusedSafely.tsx +58 -0
- package/src/visibility/react-navigation/useNavigationSafely.tsx +30 -0
- package/src/visibility/useIsAppForeground.tsx +73 -0
- package/src/visibility/useVisibility.tsx +54 -0
- package/src/visibility/useVisibilityChange.ts +69 -0
- package/src/visibility/useVisibilityChanged.tsx +69 -0
- 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
|
+
}
|