feat: add Windows and macOS support (#8570)

react-native-gesture-handler doesn't have Windows/macOS implementation yet, use the web version as stubs for now to enable navigation features for Windows and mac.

Close https://github.com/microsoft/react-native-windows/issues/3884
Close https://github.com/microsoft/react-native-windows/issues/4044
This commit is contained in:
Kai Guo
2020-07-28 14:51:41 -07:00
committed by GitHub
parent 1e813dfb5b
commit 8468c46cab
17 changed files with 134 additions and 70 deletions

View File

@@ -69,6 +69,7 @@ const SPRING_CONFIG = {
restSpeedThreshold: 0.01,
};
const ANIMATED_ZERO = new Animated.Value(0);
const ANIMATED_ONE = new Animated.Value(1);
type Binary = 0 | 1;
@@ -103,7 +104,10 @@ export default class DrawerView extends React.Component<Props> {
drawerPosition: I18nManager.isRTL ? 'left' : 'right',
drawerType: 'front',
gestureEnabled: true,
swipeEnabled: Platform.OS !== 'web',
swipeEnabled:
Platform.OS !== 'web' &&
Platform.OS !== 'windows' &&
Platform.OS !== 'macos',
swipeEdgeWidth: 32,
swipeVelocityThreshold: 500,
keyboardDismissMode: 'on-drag',
@@ -577,19 +581,19 @@ export default class DrawerView extends React.Component<Props> {
const contentTranslateX =
drawerType === 'front' || drawerType === 'permanent'
? 0
? ANIMATED_ZERO
: this.translateX;
const drawerTranslateX =
drawerType === 'permanent'
? 0
? ANIMATED_ZERO
: drawerType === 'back'
? I18nManager.isRTL
? multiply(
sub(this.containerWidth, this.drawerWidth),
isRight ? 1 : -1
)
: 0
: ANIMATED_ZERO
: this.translateX;
const offset =
@@ -649,7 +653,9 @@ export default class DrawerView extends React.Component<Props> {
</View>
{
// Disable overlay if sidebar is permanent
drawerType === 'permanent' ? null : Platform.OS === 'web' ? (
drawerType === 'permanent' ? null : Platform.OS === 'web' ||
Platform.OS === 'windows' ||
Platform.OS === 'macos' ? (
<TouchableWithoutFeedback
onPress={
gestureEnabled ? () => this.toggleDrawer(false) : undefined

View File

@@ -0,0 +1,7 @@
export {
PanGestureHandler,
TapGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -1,31 +1,7 @@
import * as React from 'react';
import { View } from 'react-native';
import type {
PanGestureHandlerProperties,
TapGestureHandlerProperties,
} from 'react-native-gesture-handler';
const Dummy: any = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const PanGestureHandler = Dummy as React.ComponentType<
PanGestureHandlerProperties
>;
export const TapGestureHandler = Dummy as React.ComponentType<
TapGestureHandlerProperties
>;
export const GestureHandlerRootView = View;
export const GestureState = {
UNDETERMINED: 0,
FAILED: 1,
BEGAN: 2,
CANCELLED: 3,
ACTIVE: 4,
END: 5,
};
export {
PanGestureHandler,
TapGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -0,0 +1,7 @@
export {
PanGestureHandler,
TapGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -0,0 +1,31 @@
import * as React from 'react';
import { View } from 'react-native';
import type {
PanGestureHandlerProperties,
TapGestureHandlerProperties,
} from 'react-native-gesture-handler';
const Dummy: any = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const PanGestureHandler = Dummy as React.ComponentType<
PanGestureHandlerProperties
>;
export const TapGestureHandler = Dummy as React.ComponentType<
TapGestureHandlerProperties
>;
export const GestureHandlerRootView = View;
export const GestureState = {
UNDETERMINED: 0,
FAILED: 1,
BEGAN: 2,
CANCELLED: 3,
ACTIVE: 4,
END: 5,
};
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -25,7 +25,14 @@ const Overlay = React.forwardRef(function Overlay(
) {
const animatedStyle = {
opacity: interpolate(progress, {
inputRange: [PROGRESS_EPSILON, 1],
// Default input range is [PROGRESS_EPSILON, 1]
// On Windows, the output value is 1 when input value is out of range for some reason
// The default value 0 will be interpolated to 1 in this case, which is not what we want.
// Therefore changing input range on Windows to [0,1] instead.
inputRange:
Platform.OS === 'windows' || Platform.OS === 'macos'
? [0, 1]
: [PROGRESS_EPSILON, 1],
outputRange: [0, 1],
}),
// We don't want the user to be able to press through the overlay when drawer is open

View File

@@ -29,7 +29,10 @@ function StackNavigator({
}: Props) {
const defaultOptions = {
gestureEnabled: Platform.OS === 'ios',
animationEnabled: Platform.OS !== 'web',
animationEnabled:
Platform.OS !== 'web' &&
Platform.OS !== 'windows' &&
Platform.OS !== 'macos',
};
const { state, descriptors, navigation } = useNavigationBuilder<

View File

@@ -0,0 +1,6 @@
export {
PanGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -1,24 +1,6 @@
import * as React from 'react';
import { View } from 'react-native';
import type { PanGestureHandlerProperties } from 'react-native-gesture-handler';
const Dummy: any = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const PanGestureHandler = Dummy as React.ComponentType<
PanGestureHandlerProperties
>;
export const GestureHandlerRootView = View;
export const GestureState = {
UNDETERMINED: 0,
FAILED: 1,
BEGAN: 2,
CANCELLED: 3,
ACTIVE: 4,
END: 5,
};
export {
PanGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -0,0 +1,6 @@
export {
PanGestureHandler,
GestureHandlerRootView,
GestureState,
} from './GestureHandlerStub';
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -0,0 +1,24 @@
import * as React from 'react';
import { View } from 'react-native';
import type { PanGestureHandlerProperties } from 'react-native-gesture-handler';
const Dummy: any = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const PanGestureHandler = Dummy as React.ComponentType<
PanGestureHandlerProperties
>;
export const GestureHandlerRootView = View;
export const GestureState = {
UNDETERMINED: 0,
FAILED: 1,
BEGAN: 2,
CANCELLED: 3,
ACTIVE: 4,
END: 5,
};
export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';

View File

@@ -0,0 +1 @@
export { default } from './MaskedViewStub';

View File

@@ -1,10 +1 @@
import type * as React from 'react';
type Props = {
maskElement: React.ReactElement;
children: React.ReactElement;
};
export default function MaskedView({ children }: Props) {
return children;
}
export { default } from './MaskedViewStub';

View File

@@ -0,0 +1 @@
export { default } from './MaskedViewStub';

View File

@@ -0,0 +1,10 @@
import type * as React from 'react';
type Props = {
maskElement: React.ReactElement;
children: React.ReactElement;
};
export default function MaskedView({ children }: Props) {
return children;
}

View File

@@ -0,0 +1,3 @@
import { TouchableOpacity } from 'react-native';
export const TouchableItem = (TouchableOpacity as any) as typeof import('./TouchableItem.native').TouchableItem;

View File

@@ -0,0 +1,3 @@
import { TouchableOpacity } from 'react-native';
export const TouchableItem = (TouchableOpacity as any) as typeof import('./TouchableItem.native').TouchableItem;