Skip to content

Commit 1a15a19

Browse files
authored
feat(react-native): Add setIosSwipeGestureEnabled (#111)
* feat(react-native): Add setIosSwipeGestureEnabled * changeset
1 parent 1c6a3c2 commit 1a15a19

File tree

5 files changed

+44
-3
lines changed

5 files changed

+44
-3
lines changed

.changeset/free-animals-show.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@granite-js/react-native': patch
3+
---
4+
5+
Add setIosSwipeGestureEnabled

packages/react-native/src/app/AppRoot.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ interface AppRootProps extends GraniteProps {
1515
container: ComponentType<PropsWithChildren<InitialProps>>;
1616
initialProps: InitialProps;
1717
initialScheme: string;
18+
setIosSwipeGestureEnabled?: ({ isEnabled }: { isEnabled: boolean }) => void;
1819
}
1920

20-
export function AppRoot({ appName, context, container: Container, initialProps, initialScheme, router }: AppRootProps) {
21+
export function AppRoot({
22+
appName,
23+
context,
24+
container: Container,
25+
initialProps,
26+
initialScheme,
27+
router,
28+
setIosSwipeGestureEnabled,
29+
}: AppRootProps) {
2130
const prefix = getSchemePrefix({
2231
appName,
2332
scheme: global.__granite.app.scheme,
@@ -35,6 +44,7 @@ export function AppRoot({ appName, context, container: Container, initialProps,
3544
initialScheme={initialScheme}
3645
container={Container}
3746
prefix={prefix}
47+
setIosSwipeGestureEnabled={setIosSwipeGestureEnabled}
3848
{...router}
3949
/>
4050
</BackEventProvider>

packages/react-native/src/app/Granite.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ export interface GraniteProps {
3131
* The initial scheme of the app.
3232
*/
3333
initialScheme?: string;
34+
35+
/**
36+
* @description
37+
* The function to set the iOS swipe gesture enabled.
38+
*/
39+
setIosSwipeGestureEnabled?: ({ isEnabled }: { isEnabled: boolean }) => void;
3440
}
3541

3642
const createApp = () => {
@@ -47,7 +53,7 @@ const createApp = () => {
4753
return {
4854
registerApp(
4955
AppContainer: ComponentType<PropsWithChildren<InitialProps>>,
50-
{ appName, context, router, initialScheme }: GraniteProps
56+
{ appName, context, router, initialScheme, setIosSwipeGestureEnabled }: GraniteProps
5157
): (initialProps: InitialProps) => JSX.Element {
5258
if (appName === ENTRY_BUNDLE_NAME) {
5359
throw new Error(`Reserved app name 'shared' cannot be used`);
@@ -59,6 +65,7 @@ const createApp = () => {
5965
container={AppContainer}
6066
initialProps={initialProps}
6167
initialScheme={initialScheme ?? getSchemeUri()}
68+
setIosSwipeGestureEnabled={setIosSwipeGestureEnabled}
6269
appName={appName}
6370
context={context}
6471
router={router}

packages/react-native/src/router/Router.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface InternalRouterProps {
5656
container: ComponentType<PropsWithChildren<InitialProps>>;
5757
initialProps: InitialProps;
5858
initialScheme: string;
59+
setIosSwipeGestureEnabled?: ({ isEnabled }: { isEnabled: boolean }) => Promise<void> | void;
5960
}
6061

6162
export type RouterProps = StackNavigatorProps & NavigationContainerProps;
@@ -129,6 +130,7 @@ export function Router({
129130
defaultScreenOption,
130131
screenContainer,
131132
// Public props (StackNavigator)
133+
setIosSwipeGestureEnabled,
132134
...navigationContainerProps
133135
}: InternalRouterProps & RouterProps): ReactElement {
134136
const initialRouteName = useInitialRouteName({ prefix, initialScheme });
@@ -163,7 +165,7 @@ export function Router({
163165

164166
return (
165167
<NavigationContainer ref={ref} {...navigationContainerProps} linking={linkingOptions}>
166-
<CanGoBackGuard canGoBack={canGoBack} onBack={onBack}>
168+
<CanGoBackGuard canGoBack={canGoBack} onBack={onBack} setIosSwipeGestureEnabled={setIosSwipeGestureEnabled}>
167169
<Container {...initialProps}>
168170
<StackNavigator.Navigator initialRouteName={initialRouteName} screenOptions={screenOptions}>
169171
{Screens}

packages/react-native/src/router/components/CanGoBackGuard.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
11
import { ReactNode, useEffect } from 'react';
22
import { BackHandler } from 'react-native';
3+
import { useIsInitialScreen } from '../hooks/useIsInitialScreen';
34

45
export function CanGoBackGuard({
56
children,
67
canGoBack,
78
onBack,
9+
setIosSwipeGestureEnabled,
810
}: {
911
canGoBack: boolean;
1012
children: ReactNode;
1113
onBack?: () => void;
14+
setIosSwipeGestureEnabled?: ({ isEnabled }: { isEnabled: boolean }) => void;
1215
}) {
16+
const isInitialScreen = useIsInitialScreen();
17+
1318
const shouldBlockGoingBack = !canGoBack;
1419

20+
useEffect(() => {
21+
if (!isInitialScreen || !canGoBack) {
22+
setIosSwipeGestureEnabled?.({ isEnabled: false });
23+
24+
return () => {
25+
setIosSwipeGestureEnabled?.({ isEnabled: true });
26+
};
27+
}
28+
29+
return;
30+
}, [canGoBack, isInitialScreen, setIosSwipeGestureEnabled]);
31+
1532
useEffect(() => {
1633
if (shouldBlockGoingBack) {
1734
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {

0 commit comments

Comments
 (0)