Skip to content

Commit 659b583

Browse files
pierpoRobin Mimeaultrobmim
authored
feat: upgrade to latest version of Expo and React (#200)
* Update react from 18 to 19 * fix: dependencies * WIP fix errors * update reaact native to version 79 * update dependencies * update expo to 53.0.9 * fix TS-IGNORE * re add comments back from last commit * chore: update yarn lock * refactor: revert to original react 18 code so that typescript compiles * fix(typescript): adjust ref types * chore: fix tests after react upgrade --------- Co-authored-by: Robin Mimeault <[email protected]> Co-authored-by: robmim <[email protected]>
1 parent a9cadbc commit 659b583

File tree

16 files changed

+3431
-4774
lines changed

16 files changed

+3431
-4774
lines changed

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
"private": true,
77
"packageManager": "[email protected]",
88
"devDependencies": {
9-
"@babel/core": "^7.22.5",
9+
"@babel/core": "^7.26.0",
1010
"@babel/preset-env": "^7.22.5",
1111
"@babel/preset-react": "^7.22.5",
1212
"@babel/preset-typescript": "^7.22.5",
1313
"@react-native-community/eslint-config": "^3.2.0",
14-
"@testing-library/react-native": "^12.4.3",
15-
"@types/react": "~18.2.79",
16-
"@types/react-dom": "~18.2.25",
14+
"@testing-library/react-native": "^13.2.0",
15+
"@types/react": "~19.0.0",
16+
"@types/react-dom": "~19.0.0",
1717
"@typescript-eslint/eslint-plugin": "^5.60.1",
1818
"@typescript-eslint/parser": "^5.60.1",
1919
"@typescript-eslint/typescript-estree": "^5.61.0",
@@ -32,20 +32,21 @@
3232
"metro-react-native-babel-preset": "^0.76.7",
3333
"patch-package": "^8.0.0",
3434
"prettier": "^2.8.8",
35+
"react-test-renderer": "19.0.0",
3536
"style-loader": "^3.3.3",
3637
"ts-loader": "^9.4.4",
37-
"typescript": "~5.3.3",
38+
"typescript": "~5.8.3",
3839
"webpack": "^5.88.1",
3940
"webpack-cli": "^5.1.4",
4041
"webpack-dev-server": "^4.15.1"
4142
},
4243
"dependencies": {
4344
"@react-native-tvos/config-tv": "^0.0.4",
4445
"@react-navigation/bottom-tabs": "^6.5.11",
45-
"react": "18.2.0",
46-
"react-dom": "18.2.0",
46+
"react": "19.0.0",
47+
"react-dom": "19.0.0",
4748
"react-native-modal": "^13.0.1",
48-
"react-native-web": "^0.19.6"
49+
"react-native-web": "^0.20.0"
4950
},
5051
"resolutions": {
5152
"@typescript-eslint/typescript-estree": "5.61.0"
Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
// This is only used by jest
22
module.exports = {
33
sourceMaps: 'inline',
4-
presets: [
5-
'module:metro-react-native-babel-preset',
6-
'@babel/preset-env',
7-
[
8-
'@babel/preset-react',
9-
{
10-
runtime: 'automatic',
11-
},
12-
],
13-
'@babel/preset-typescript',
14-
],
4+
presets: ['module:@react-native/babel-preset'],
155
plugins: [
166
[
177
'module-resolver',
@@ -21,6 +11,5 @@ module.exports = {
2111
},
2212
},
2313
],
24-
['@babel/plugin-proposal-class-properties', { loose: false }],
2514
],
2615
};

packages/example/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const packagesToTransform = [
2222

2323
/** @type {import('@jest/types').Config.InitialOptions} */
2424
const config = {
25-
preset: '@testing-library/react-native',
25+
preset: 'react-native',
2626
/*
2727
* What the preset provides:
2828
* - a transformer to handle media assets (png, video)

packages/example/package.json

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,28 @@
1515
"@bam.tech/react-native-keyevent-expo-config-plugin": "^1.0.52",
1616
"@emotion/native": "^11.11.0",
1717
"@emotion/react": "^11.11.3",
18-
"@expo/metro-runtime": "~3.2.1",
18+
"@expo/metro-runtime": "~5.0.4",
1919
"@react-navigation/native": "^6.1.9",
2020
"@react-navigation/native-stack": "^6.9.17",
2121
"@types/jest": "^29.5.12",
2222
"@types/react-test-renderer": "^18.0.7",
2323
"babel-jest": "^29.7.0",
24-
"expo": "~51.0.9",
25-
"expo-status-bar": "~1.12.1",
24+
"expo": "~53.0.9",
25+
"expo-status-bar": "~2.2.3",
2626
"jest": "^29.7.0",
2727
"jest-environment-jsdom": "^29.7.0",
2828
"jest-watch-typeahead": "^2.2.2",
2929
"lucide-react-native": "^0.335.0",
30-
"react": "18.2.0",
31-
"react-native": "npm:react-native-tvos@0.74.1-0",
30+
"react": "19.0.0",
31+
"react-native": "npm:react-native-tvos@0.79.1-1",
3232
"react-native-keyevent": "^0.3.2",
33-
"react-native-safe-area-context": "4.10.1",
34-
"react-native-screens": "3.31.1",
35-
"react-native-svg": "15.2.0",
36-
"react-test-renderer": "^18.2.0",
37-
"typescript": "^5.6.2"
33+
"react-native-safe-area-context": "5.4.0",
34+
"react-native-screens": "~4.10.0",
35+
"react-native-svg": "15.11.2",
36+
"typescript": "~5.8.3"
3837
},
3938
"devDependencies": {
40-
"@babel/core": "^7.24.0",
39+
"@babel/core": "^7.26.0",
4140
"babel-plugin-module-resolver": "^5.0.0"
4241
},
4342
"private": true,

packages/example/src/testing/jest-setupAfterEnv.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import '@testing-library/react-native/extend-expect';
2-
31
import { TEST_DEFAULT_DATE, TEST_DEFAULT_MATH_RANDOM } from './constants';
42

53
/**

packages/lib/babel.jest.config.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
// This is only used by jest
22
module.exports = {
33
sourceMaps: 'inline',
4-
presets: [
5-
'module:metro-react-native-babel-preset',
6-
'@babel/preset-env',
7-
[
8-
'@babel/preset-react',
9-
{
10-
runtime: 'automatic',
11-
},
12-
],
13-
'@babel/preset-typescript',
14-
],
15-
plugins: [['@babel/plugin-proposal-class-properties', { loose: false }]],
4+
presets: ['module:@react-native/babel-preset'],
165
};

packages/lib/jest.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const path = require('path');
1313

1414
const packagesToTransform = [
1515
'react-native',
16-
'react-native-(.*)',
16+
'react-native-.*',
1717
'@react-native',
1818
'@react-native-community',
1919
'@react-native-tvos',
@@ -22,7 +22,7 @@ const packagesToTransform = [
2222

2323
/** @type {import('@jest/types').Config.InitialOptions} */
2424
const config = {
25-
preset: '@testing-library/react-native',
25+
preset: 'react-native',
2626
/*
2727
* What the preset provides:
2828
* - a transformer to handle media assets (png, video)
@@ -40,7 +40,7 @@ const config = {
4040
{ configFile: path.resolve(__dirname, './babel.jest.config.js') },
4141
],
4242
},
43-
transformIgnorePatterns: [`node_modules/(?!(${packagesToTransform.join('|')})/)`],
43+
transformIgnorePatterns: [`node_modules/(?!(${packagesToTransform.join('|')})(/|$))`],
4444
cacheDirectory: '.cache/jest',
4545
// coverage
4646
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],

packages/lib/src/spatial-navigation/components/Node.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,10 @@ const useScrollToNodeIfNeeded = ({
5757
childRef,
5858
additionalOffset,
5959
}: {
60-
childRef: React.MutableRefObject<View | null>;
60+
childRef: React.RefObject<View | null>;
6161
additionalOffset?: number;
6262
}) => {
6363
const { scrollToNodeIfNeeded } = useSpatialNavigatorParentScroll();
64-
6564
return () => scrollToNodeIfNeeded(childRef, additionalOffset);
6665
};
6766

@@ -70,6 +69,7 @@ const useBindRefToChild = () => {
7069

7170
const bindRefToChild = (child: React.ReactElement) => {
7271
return React.cloneElement(child, {
72+
// @ts-expect-error @fixme can't find how to type this properly -- new error since react 19
7373
...child.props,
7474
ref: (node: View) => {
7575
// We need the reference for our scroll handling
@@ -138,26 +138,25 @@ export const SpatialNavigationNode = forwardRef<SpatialNavigationNodeRef, Props>
138138
* Therefore, the SpatialNavigator Node callbacks are registered at 1st render but can change (ie. if props change) afterwards.
139139
* Since we want the functions to always be up to date, we use a reference to them.
140140
*/
141-
142-
const currentOnSelect = useRef<() => void>();
141+
const currentOnSelect = useRef<() => void>(undefined);
143142
currentOnSelect.current = onSelect;
144143

145-
const currentOnLongSelect = useRef<() => void>();
144+
const currentOnLongSelect = useRef<() => void>(undefined);
146145
currentOnLongSelect.current = onLongSelect;
147146

148-
const currentOnFocus = useRef<() => void>();
147+
const currentOnFocus = useRef<() => void>(undefined);
149148
currentOnFocus.current = () => {
150149
onFocus?.();
151150
scrollToNodeIfNeeded();
152151
};
153152

154-
const currentOnBlur = useRef<() => void>();
153+
const currentOnBlur = useRef<() => void>(undefined);
155154
currentOnBlur.current = onBlur;
156155

157-
const currentOnActive = useRef<() => void>();
156+
const currentOnActive = useRef<() => void>(undefined);
158157
currentOnActive.current = onActive;
159158

160-
const currentOnInactive = useRef<() => void>();
159+
const currentOnInactive = useRef<() => void>(undefined);
161160
currentOnInactive.current = onInactive;
162161

163162
const shouldHaveDefaultFocus = useSpatialNavigatorDefaultFocus();
@@ -210,7 +209,7 @@ export const SpatialNavigationNode = forwardRef<SpatialNavigationNodeRef, Props>
210209
}, [id, isFocusable, shouldHaveDefaultFocus, spatialNavigator]);
211210

212211
// This proxy allows to track whether a property is used or not
213-
// hence allowing to ignore re-renders for unused properties
212+
// hence allowing to ignore re-renders for unused pr
214213
const proxyObject = new Proxy(
215214
{ isFocused, isActive, isRootActive },
216215
{

packages/lib/src/spatial-navigation/components/ScrollView/ScrollView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const SpatialNavigationScrollView = forwardRef<ScrollView, Props>(
7575
useRemotePointerScrollviewScrollProps({ pointerScrollSpeed, scrollY, scrollViewRef });
7676

7777
const scrollToNode = useCallback(
78-
(newlyFocusedElementRef: RefObject<View>, additionalOffset = 0) => {
78+
(newlyFocusedElementRef: RefObject<View | null>, additionalOffset = 0) => {
7979
try {
8080
if (deviceTypeRef.current === 'remoteKeys') {
8181
newlyFocusedElementRef?.current?.measureLayout(

packages/lib/src/spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedList.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('SpatialNavigationVirtualizedList', () => {
5858
);
5959

6060
// This is bad practice but easiest way to access the ref from outside the component for testing
61-
let currentListRef: React.RefObject<SpatialNavigationVirtualizedListRef>;
61+
let currentListRef: React.RefObject<SpatialNavigationVirtualizedListRef | null>;
6262
const VirtualizedListWithNavigationButtons = ({ listSize = 10 }) => {
6363
currentListRef = useRef<SpatialNavigationVirtualizedListRef>(null);
6464

0 commit comments

Comments
 (0)