Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refact: remove mixed CJS/ESM, refactorize index.native.tsx #1982

Merged
merged 39 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7e0bf34
Change @react-native-community/bob to react-native-builder-bob
tboba Nov 28, 2023
340c548
Revert removing `husky install` from prepare task
tboba Nov 28, 2023
8493f67
Change syntax of files in package.json, remove unncessary files
tboba Nov 28, 2023
9b6bf09
Change commonjs to module
tboba Nov 28, 2023
f955f52
Add file formats to file paths
tboba Nov 28, 2023
ce62286
Change all `function` to `const` in index.native.tsx
tboba Nov 29, 2023
19e038e
Change module.exports to export default in index.native.tsx
tboba Nov 29, 2023
0917432
Migrate index.native.tsx from mixed CJS/ESM to ESM-only
tboba Nov 30, 2023
04d811e
Remove main field and file formats from package.json
tboba Nov 30, 2023
2b872ff
Change function to const in HeaderConfig
tboba Nov 30, 2023
9e12ce0
Fix issue with not working ScreenStackHeaderConfig, change export def…
tboba Nov 30, 2023
d61df9b
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Dec 1, 2023
8075462
[2nd STAGE] [POC] Move everything from index.native.tsx
tboba Dec 1, 2023
ce4b463
Adjust index.tsx to current refactor
tboba Dec 1, 2023
6c44ee7
Correct imports
tboba Dec 1, 2023
6a46ed4
Add comments about native components
tboba Dec 5, 2023
b84ed00
Add comments about components to index.native.tsx
tboba Dec 5, 2023
30873a0
Bring `main` field back to package.json
tboba Dec 5, 2023
2e3316d
Remove remaining comment from index.native.tsx
tboba Dec 5, 2023
e677024
Remove version check for enableFreeze
tboba Dec 5, 2023
2cfce53
correct comment of formSheet in Screen.tsx
tboba Dec 5, 2023
e67b1ca
Move everything to main index.tsx
tboba Dec 6, 2023
a05ce59
Move ScreenStack to ScreenStack.web.tsx
tboba Dec 6, 2023
8a7da07
Fully unify index.tsx file, add additional .web.tsx files
tboba Dec 7, 2023
381d249
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Dec 7, 2023
edd2934
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Dec 18, 2023
52e3078
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Dec 21, 2023
c175db9
Revert generating CJS
tboba Dec 21, 2023
f7ebf18
Revert changing function to arrow functions
tboba Dec 21, 2023
80db1e2
Move React insert to the top
tboba Dec 21, 2023
c48929b
Add export default HeaderConfig at the bottom of file
tboba Dec 21, 2023
5c3a8cd
Revert adding export default HeaderConfig at the bgpottom of file
tboba Dec 21, 2023
38bd695
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Jan 2, 2024
6c64d70
Remove index.native.tsx leftover
tboba Jan 2, 2024
2a6eedd
Change console.warn
tboba Jan 3, 2024
f50265b
Merge branch 'main' into @tboba/remove-mixed-cjs
tboba Jan 18, 2024
f62eeb7
Adjust changes from merge
tboba Jan 18, 2024
989e545
Move eslintIgnore and codegenConfig where it was before
tboba Jan 18, 2024
eb3a635
Fix wrongly written context
tboba Jan 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion native-stack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"main": "../lib/commonjs/native-stack/index",
"module": "../lib/module/native-stack/index",
"react-native": "../src/native-stack/index",
"types": "../lib/typescript/native-stack/index"
"types": "../lib/typescript/native-stack/index.d.ts"
tboba marked this conversation as resolved.
Show resolved Hide resolved
}
36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"module": "lib/module/index",
"react-native": "src/index",
"source": "src/index",
"types": "lib/typescript/index",
"types": "lib/typescript/index.d.ts",
"files": [
"src/",
"common/",
Expand Down Expand Up @@ -67,17 +67,16 @@
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "7.22.15",
"@react-native-community/bob": "^0.17.1",
"@react-native-community/cli": "^11.3.6",
"@react-native-community/cli-platform-android": "^11.3.6",
"@react-native-community/cli-platform-ios": "^11.3.6",
"@react-navigation/native": "^5.8.0",
"@react-navigation/stack": "^5.10.0",
"@types/jest": "^29.3.1",
"@types/react": "^18.2.21",
"@types/react-test-renderer": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"@react-native-community/cli": "^11.3.6",
"@react-native-community/cli-platform-android": "^11.3.6",
"@react-native-community/cli-platform-ios": "^11.3.6",
"babel-jest": "^29.6.4",
"clang-format": "^1.8.0",
"eslint": "^8.19.0",
Expand All @@ -98,6 +97,7 @@
"react": "18.2.0",
"react-dom": "^18.2.0",
"react-native": "0.72.4",
"react-native-builder-bob": "^0.23.2",
"react-native-reanimated": "^2.2.0",
"react-native-safe-area-context": "^4.8.1",
"react-native-windows": "^0.64.8",
Expand All @@ -117,7 +117,19 @@
"android/**/*.kt": "yarn format-android",
"ios/**/*.{h,m,mm,cpp}": "yarn format-ios"
},
"@react-native-community/bob": {
"eslintIgnore": [
"node_modules/",
"lib/"
],
"codegenConfig": {
"name": "rnscreens",
"type": "components",
"jsSrcsDir": "./src/fabric",
"android": {
"javaPackageName": "com.swmansion.rnscreens"
}
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
Expand All @@ -130,17 +142,5 @@
}
]
]
},
"eslintIgnore": [
"node_modules/",
"lib/"
],
"codegenConfig": {
"name": "rnscreens",
"type": "components",
"jsSrcsDir": "./src/fabric",
"android": {
"javaPackageName": "com.swmansion.rnscreens"
}
}
}
2 changes: 1 addition & 1 deletion reanimated/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"main": "../lib/commonjs/reanimated/index",
"module": "../lib/module/reanimated/index",
"react-native": "../src/reanimated/index",
"types": "../lib/typescript/reanimated/index"
"types": "../lib/typescript/reanimated/index.d.ts"
}
25 changes: 25 additions & 0 deletions src/components/FullWindowOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { PropsWithChildren, ReactNode } from 'react';
import { Platform, StyleProp, View, ViewStyle } from 'react-native';

// Native components
import FullWindowOverlayNativeComponent from '../fabric/FullWindowOverlayNativeComponent';
const NativeFullWindowOverlay: React.ComponentType<
WoLewicki marked this conversation as resolved.
Show resolved Hide resolved
PropsWithChildren<{
style: StyleProp<ViewStyle>;
}>
> = FullWindowOverlayNativeComponent as any;

Check warning on line 10 in src/components/FullWindowOverlay.tsx

View workflow job for this annotation

GitHub Actions / install-and-lint

Unexpected any. Specify a different type

function FullWindowOverlay(props: { children: ReactNode }) {
if (Platform.OS !== 'ios') {
console.warn('Importing FullWindowOverlay is only valid on iOS devices.');
tboba marked this conversation as resolved.
Show resolved Hide resolved
return <View {...props} />;
}
return (
<NativeFullWindowOverlay
style={{ position: 'absolute', width: '100%', height: '100%' }}>
{props.children}
</NativeFullWindowOverlay>
);
}

export default FullWindowOverlay;
6 changes: 6 additions & 0 deletions src/components/FullWindowOverlay.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { View } from 'react-native';
import React, { ReactNode } from 'react';

export default View as React.ComponentType<{
children: ReactNode;
}>;
194 changes: 194 additions & 0 deletions src/components/Screen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import React from 'react';
import { Animated, View } from 'react-native';

import TransitionProgressContext from '../TransitionProgressContext';
import DelayedFreeze from './helpers/DelayedFreeze';
import { ScreenProps } from 'react-native-screens';

import {
freezeEnabled,
isNativePlatformSupported,
screensEnabled,
} from '../core';

// Native components
import ScreenNativeComponent from '../fabric/ScreenNativeComponent';

export const NativeScreen: React.ComponentType<ScreenProps> =
ScreenNativeComponent as any;

Check warning on line 19 in src/components/Screen.tsx

View workflow job for this annotation

GitHub Actions / install-and-lint

Unexpected any. Specify a different type
let AnimatedNativeScreen: React.ComponentType<ScreenProps>;

// Incomplete type, all accessible properties available at:
// react-native/Libraries/Components/View/ReactNativeViewViewConfig.js
interface ViewConfig extends View {
viewConfig: {
validAttributes: {
style: {
display: boolean;
};
};
};
}

export class InnerScreen extends React.Component<ScreenProps> {
private ref: React.ElementRef<typeof View> | null = null;
private closing = new Animated.Value(0);
private progress = new Animated.Value(0);
private goingForward = new Animated.Value(0);

setNativeProps(props: ScreenProps): void {
this.ref?.setNativeProps(props);
}

setRef = (ref: React.ElementRef<typeof View> | null): void => {
this.ref = ref;
this.props.onComponentRef?.(ref);
};

render() {
const {
enabled = screensEnabled(),
freezeOnBlur = freezeEnabled(),
...rest
} = this.props;

// To maintain default behavior of formSheet stack presentation style and to have reasonable
// defaults for new medium-detent iOS API we need to set defaults here
const {
sheetAllowedDetents = 'large',
sheetLargestUndimmedDetent = 'all',
sheetGrabberVisible = false,
sheetCornerRadius = -1.0,
sheetExpandsWhenScrolledToEdge = true,
} = rest;

if (enabled && isNativePlatformSupported) {
AnimatedNativeScreen =
AnimatedNativeScreen || Animated.createAnimatedComponent(NativeScreen);

let {
// Filter out active prop in this case because it is unused and
// can cause problems depending on react-native version:
// https://github.com/react-navigation/react-navigation/issues/4886
active,
activityState,
children,
isNativeStack,
gestureResponseDistance,
onGestureCancel,
...props
} = rest;

if (active !== undefined && activityState === undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we will remove the active prop and code related to it in v4, just a note for future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for mentioning that. We can do that in a separate PR 👍

console.warn(
'It appears that you are using old version of react-navigation library. Please update @react-navigation/bottom-tabs, @react-navigation/stack and @react-navigation/drawer to version 5.10.0 or above to take full advantage of new functionality added to react-native-screens'
);
activityState = active !== 0 ? 2 : 0; // in the new version, we need one of the screens to have value of 2 after the transition
}

const handleRef = (ref: ViewConfig) => {
if (ref?.viewConfig?.validAttributes?.style) {
ref.viewConfig.validAttributes.style = {
...ref.viewConfig.validAttributes.style,
display: false,
};
this.setRef(ref);
}
};

return (
<DelayedFreeze freeze={freezeOnBlur && activityState === 0}>
<AnimatedNativeScreen
{...props}
activityState={activityState}
sheetAllowedDetents={sheetAllowedDetents}
sheetLargestUndimmedDetent={sheetLargestUndimmedDetent}
sheetGrabberVisible={sheetGrabberVisible}
sheetCornerRadius={sheetCornerRadius}
sheetExpandsWhenScrolledToEdge={sheetExpandsWhenScrolledToEdge}
gestureResponseDistance={{
start: gestureResponseDistance?.start ?? -1,
end: gestureResponseDistance?.end ?? -1,
top: gestureResponseDistance?.top ?? -1,
bottom: gestureResponseDistance?.bottom ?? -1,
}}
// This prevents showing blank screen when navigating between multiple screens with freezing
// https://github.com/software-mansion/react-native-screens/pull/1208
ref={handleRef}
onTransitionProgress={
!isNativeStack
? undefined
: Animated.event(
[
{
nativeEvent: {
progress: this.progress,
closing: this.closing,
goingForward: this.goingForward,
},
},
],
{ useNativeDriver: true }
)
}
onGestureCancel={
onGestureCancel ??
(() => {
// for internal use
})
}>
{!isNativeStack ? ( // see comment of this prop in types.tsx for information why it is needed
children
) : (
<TransitionProgressContext.Provider
value={{
progress: this.progress,
closing: this.closing,
goingForward: this.goingForward,
}}>
{children}
</TransitionProgressContext.Provider>
)}
</AnimatedNativeScreen>
</DelayedFreeze>
);
} else {
// same reason as above
let {
active,
activityState,
style,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onComponentRef,
...props
} = rest;

if (active !== undefined && activityState === undefined) {
activityState = active !== 0 ? 2 : 0;
}
return (
<Animated.View
style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}
ref={this.setRef}
{...props}
/>
);
}
}
}

// context to be used when the user wants to use enhanced implementation
// e.g. to use `useReanimatedTransitionProgress` (see `reanimated` folder in repo)
export const ScreenContext = React.createContext(InnerScreen);

class Screen extends React.Component<ScreenProps> {
static contextType = ScreenContext;

render() {
const ScreenWrapper = (this.context || InnerScreen) as React.ElementType;
return <ScreenWrapper {...this.props} />;
}
}

export default Screen;
43 changes: 43 additions & 0 deletions src/components/Screen.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ScreenProps } from 'react-native-screens';
import { Animated, View } from 'react-native';
import React from 'react';

import { screensEnabled } from '../core';

export const InnerScreen = View;

// We're using class component here because of the error from reanimated:
// createAnimatedComponent` does not support stateless functional components; use a class component instead.
export class NativeScreen extends React.Component<ScreenProps> {
render(): JSX.Element {
let {
active,
activityState,
style,
enabled = screensEnabled(),
...rest
} = this.props;

if (enabled) {
if (active !== undefined && activityState === undefined) {
activityState = active !== 0 ? 2 : 0; // change taken from index.native.tsx
}
return (
<View
// @ts-expect-error: hidden exists on web, but not in React Native
hidden={activityState === 0}
style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}
{...rest}
/>
);
}

return <View {...rest} />;
}
}

const Screen = Animated.createAnimatedComponent(NativeScreen);

export const ScreenContext = React.createContext(Screen);

export default Screen;
33 changes: 33 additions & 0 deletions src/components/ScreenContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Platform, View } from 'react-native';
import React from 'react';
import { ScreenContainerProps } from 'react-native-screens';
import { isNativePlatformSupported, screensEnabled } from '../core';

// Native components
import ScreenContainerNativeComponent from '../fabric/ScreenContainerNativeComponent';
import ScreenNavigationContainerNativeComponent from '../fabric/ScreenNavigationContainerNativeComponent';

export const NativeScreenContainer: React.ComponentType<ScreenContainerProps> =
Platform.OS !== 'web' ? (ScreenContainerNativeComponent as any) : View;

Check warning on line 11 in src/components/ScreenContainer.tsx

View workflow job for this annotation

GitHub Actions / install-and-lint

Unexpected any. Specify a different type
export const NativeScreenNavigationContainer: React.ComponentType<ScreenContainerProps> =
Platform.OS !== 'web'
? (ScreenNavigationContainerNativeComponent as any)

Check warning on line 14 in src/components/ScreenContainer.tsx

View workflow job for this annotation

GitHub Actions / install-and-lint

Unexpected any. Specify a different type
: View;

function ScreenContainer(props: ScreenContainerProps) {
const { enabled = screensEnabled(), hasTwoStates, ...rest } = props;

if (enabled && isNativePlatformSupported) {
if (hasTwoStates) {
const ScreenNavigationContainer =
Platform.OS === 'ios'
? NativeScreenNavigationContainer
: NativeScreenContainer;
return <ScreenNavigationContainer {...rest} />;
}
return <NativeScreenContainer {...rest} />;
}
return <View {...rest} />;
}

export default ScreenContainer;
Loading
Loading