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

chore(exoflex): update react, react-native & react-native-paper version #713

Merged

Conversation

StefanusChristian
Copy link
Contributor

@StefanusChristian StefanusChristian commented Jan 25, 2023

Changes:

Package & Example app changes:

  • Upgrade react, react-native, react-native-web, react-native-paper, react-native-collapsible version.
  • Change react-native-calendars from Yoan repository into latest version. (changes from @JonathanRadotski https://github.com/StefanusChristian/infra/pull/1/files)
  • Add new expo project in example directory. Since the previous one was still in SDK40, it is easier to create a new one instead of updating it to SDK47.
  • Add patch-package to both exoflex (patch react-native-collapsible) & exoflex/new-example (patch react-navigation-drawer).

Adjusted Component:

  • Accordion: Add useNativeRiver props to useAnimation()
  • Badge: Add textStyle typing
  • Button:
    • ButtonOpacity:
      • Update ref as RefObject<TouchableOpacity> since ButtonProp types based on react-native-paper types and the ref was RefObject<View> (from Surface component).
      • Adjust usage of accessibilityTraits & accessibilityComponentType into accessibilityStates. (Reference)
      • Adjust Icon props naming from color to iconColor.
    • ButtonRipple:
      • Adjust usage of accessibilityTraits & accessibilityComponentType into accessibilityStates.
      • Adjust Icon props naming from color to iconColor.
  • Calendar: Adjust CalendarProps to follow latest version of the package.
  • Chip: Adjust Icon props naming from color to iconColor.
  • Collapsible: Add useNativeRiver props to useAnimation()
  • DateTimePicker: Adjust DateTimePicker.web type from DateObject into DateData.
  • Menu: Adjust PaperMenu.Item props naming from icon to leadingIcon.
  • SegmentedControl: Add StyleProp<ViewStyle> in both Indicator & SegmentedControl.
  • Switch: Add StyleProp<ViewStyle> types.
  • Toast: Adjust Icon props naming from color to iconColor.

Contants, Helper & Types Changes:

  • Theme: Add 2 new color key as part of the Theme: notification & tooltip.
  • getPaperTheme: Adjust import naming from Theme into MD2Theme and adjust the props needed.
  • Colors types: Add new key tooltip as Colors type.
  • Custom react-native-color-slider types: Change number[] into Array<number>

How to test:

  • Move to packages/exoflex and run yarn install to install dependencies.
  • Move to packages/exoflex/example and also run yarn install. Once it's done, run yarn start to test the component.

Notes:

Based on testing, the only component that has problem is ButtonRipple. The button didn't work properly on iOS simulator, but animation run properly on Android (cc: @JonathanRadotski @Udayawibawamukti).

@StefanusChristian StefanusChristian added the wip Work in progress label Jan 25, 2023
@StefanusChristian StefanusChristian force-pushed the exoflex/accessibilityTraits-error branch from e1722b9 to 538739c Compare January 27, 2023 06:18
@StefanusChristian StefanusChristian marked this pull request as ready for review January 27, 2023 09:02
@StefanusChristian StefanusChristian added ready for review and removed wip Work in progress labels Jan 30, 2023
@StefanusChristian StefanusChristian force-pushed the exoflex/accessibilityTraits-error branch from aa66095 to 69a8904 Compare January 30, 2023 08:20
ikusa
ikusa previously approved these changes Jan 30, 2023
Copy link
Contributor

@ikusa ikusa left a comment

Choose a reason for hiding this comment

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

Thanks for upgrading all of these. The changes looks good but I've several suggestion and question. We also might need @darcien help to review these too, since I'm not super familiar with exoflex

"react-native-animation-hooks": "^1.0.1",
"react-native-calendars": "https://github.com/oshimayoan/react-native-calendars/archive/oshimayoan-0.0.3.tar.gz",
"react-native-collapsible": "^1.5.1",
"react-native-calendars": "^1.1293.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

On reverting this to the newest feat, have we test these change support what Yoan originally patch out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's already supported on the newest version, but let me include @JonathanRadotski to the discussion. What do you think?

Copy link
Contributor

@JonathanRadotski JonathanRadotski Feb 1, 2023

Choose a reason for hiding this comment

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

Briefly checked and comparing added feature. I think the newest version is already supported with added feature from previous package and good to go 👍.

packages/exoflex/example/metro.config.js Outdated Show resolved Hide resolved
diff --git a/node_modules/react-navigation-drawer/lib/module/views/Drawer.js b/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
index 3f81450..cf976b7 100644
--- a/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
+++ b/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
Copy link
Contributor

Choose a reason for hiding this comment

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

After checking the issue, from my understanding it seems this was caused by we using react-navigation 4. It's not required to do this now but I think it's good to also upgrade it to react-navigation 5/6.

Copy link
Contributor

Choose a reason for hiding this comment

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

If the upgrade is not a 5 mins job, lets just land this first and upgrade on separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, will try and report later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Based on this: https://reactnavigation.org/docs/5.x/upgrading-from-4.x#navigation-container

I thinks it's better to upgrade on separate PR, since we still using createAppContainer to wrap our RootNavigator.

: !!renderIconRight
? renderIconRight(animatedValue)
: DefaultIcon}
<>
Copy link
Contributor

Choose a reason for hiding this comment

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

I've checked out these changes and it seems now will throw error when we use more than one child. Is this supposed to work like that? or is it possible we messed up with something? React native doc say View is designed to be nested inside other views and can have 0 to many children of any type.

Copy link
Contributor

Choose a reason for hiding this comment

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

Might be something from the collapsible package we use which attach a gesture handler to the children, requiring specifically only 1 child. Need investigation as I don't remember the detail here.

packages/exoflex/tsconfig.json Outdated Show resolved Hide resolved
@ikusa
Copy link
Contributor

ikusa commented Jan 30, 2023

@StefanusChristian Also do we have the example of buttonRipple not working properly on the IOS? curious what's the actual result of these bug

packages/exoflex/example/tsconfig.json Outdated Show resolved Hide resolved
diff --git a/node_modules/react-navigation-drawer/lib/module/views/Drawer.js b/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
index 3f81450..cf976b7 100644
--- a/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
+++ b/node_modules/react-navigation-drawer/lib/module/views/Drawer.js
Copy link
Contributor

Choose a reason for hiding this comment

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

If the upgrade is not a 5 mins job, lets just land this first and upgrade on separate PR

@@ -38,19 +39,18 @@ export default function ButtonOpacity(props: ButtonProps) {
return (
<TouchableOpacity
{...otherProps}
ref={ref as RefObject<TouchableOpacity>}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if passing ref directly will work or not.
This will need a bit of testing and see if this needs use forwardRef instead.

For now I think this is OK, just make sure to not release this before testing whether the ref works or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, will test it.

Copy link
Contributor Author

@StefanusChristian StefanusChristian Feb 1, 2023

Choose a reason for hiding this comment

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

@ikusa @darcien

About this problem, I think I'll open up a discussion in here. So the initial reason why I add this change was because the parent exoflex Button component has props with type ButtonProps which inherit PaperButton types.

PaperButton props type also inherit PaperSurface type, which has the ref prop with type React.RefObject<View>

Our exoflex Button has 2 type: ButtonOpacity & ButtonRipple, which will rendered based on useRipple props.

With ButtonRipple, which will render TouchableRipple from react-native-paper, it seems the passed <React.RefObject<View>> ref from ButtonProps didn't raise any type error. Turns out TouchableRipple inherits its prop type from RN Pressable and also has the forwardedRef - React.RefAttributes<View>.

But with ButtonOpacity, which will render TouchableOpacity from react-native, it raises ref type error. Because the desired type was LegacyRef<TouchableOpacity> but supplied with RefObject<View>. That's why I passing the ref like that and typecast it as RefObject<TouchableOpacity> to fulfilled the required type.

As for using the forwardRef, the same problem arise when I need to type the ref from using forwardRef on Parent Button component.

Maybe you guys can enlighten me on how to solve this problem?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's been a while since I worked on this area, so it might be a bit hard to give exact code solution.

From a glance, we should be able to resolve this type conflict by migrating away from TouchableOpacity and use Pressable instead. That way the ref is always a View ref.

The cons: we need to mimic the old TouchableOpacity using Pressable to keep the same behavior. Unless we want to change the default button behavior, and just do a breaking changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ikusa @darcien

Got it! Changes on using Pressable are in this commit: e46eaf3

I added animated opacity to make the feedback looks like TouchableOpacity and it seems to work as intended.

Pressable.Opacity.mp4

Copy link
Contributor

@darcien darcien Feb 3, 2023

Choose a reason for hiding this comment

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

Looks great 👍

You might want to put the animated value in a ref and memoize the fade transition functions for optimizations.

Also, probably it's not a good idea to override the onPressIn/onPressOut from other props with our fade animation. Will need to extend it so we also call the onPressIn/onPressOut from the props.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it! Applied in here: 4971cb9

packages/exoflex/src/components/Badge.tsx Outdated Show resolved Hide resolved
: !!renderIconRight
? renderIconRight(animatedValue)
: DefaultIcon}
<>
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be something from the collapsible package we use which attach a gesture handler to the children, requiring specifically only 1 child. Need investigation as I don't remember the detail here.

packages/exoflex/example/webpack.config.js Show resolved Hide resolved
@darcien
Copy link
Contributor

darcien commented Jan 30, 2023

Great work @StefanusChristian! We might need to update the repo settings before merging your changes because right now it's blocked by a dead circleci check.

@StefanusChristian
Copy link
Contributor Author

@ikusa @darcien
Here's the video showing the ButtonRipple problem on iOS. The button onPress is invoked but didn't show the ripple animation at all.

Button.Ripple.Problem.mp4

@darcien
Copy link
Contributor

darcien commented Feb 1, 2023

Let's not block the upgrade PR on the button ripple issue. I'm keen to ship this B I G P R ASAP and address the minor issues separately.

Copy link
Contributor

@darcien darcien left a comment

Choose a reason for hiding this comment

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

note on the memo dependency issue

Comment on lines +47 to +48
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not disable this lint rule and fix the warning.

Not setting the dependency for useCallback correctly might cause subtle bugs with stale values.

Actually, let's do optimization separately now that I think about it. See my next comment.

Comment on lines +62 to +65
onPressIn={(e) => {
onPressIn && onPressIn(e);
fadeOpacityIn();
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

Here, we create another arrow function inline, which is the thing we want to optimize before by moving the arrow function to useCallback.

If you want a deep dive on this, beta docs from React is a good starting point, like: https://beta.reactjs.org/reference/react/useCallback#should-you-add-usecallback-everywhere

But in the meantime, let's just keep the fix in and iterate on the optimization later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, will do.
For the repo setting (remove/bypass the circleci check), do you have the authority for that @darcien? I think I don't have the permission, so I can't adjust the setting

@darcien
Copy link
Contributor

darcien commented Feb 6, 2023

For the repo setting (remove/bypass the circleci check), do you have the authority for that @darcien? I think I don't have the permission, so I can't adjust the setting

I've removed the required CircleCI check for merging the PR.
In the future, we will need to migrate the CI.

@StefanusChristian can you try running the tests locally and see if it passes?
After that is checked, we should be good to go

@StefanusChristian
Copy link
Contributor Author

For the repo setting (remove/bypass the circleci check), do you have the authority for that @darcien? I think I don't have the permission, so I can't adjust the setting

I've removed the required CircleCI check for merging the PR. In the future, we will need to migrate the CI.

@StefanusChristian can you try running the tests locally and see if it passes? After that is checked, we should be good to go

Screen Shot 2023-02-07 at 11 05 35 AM

Screen Shot 2023-02-07 at 11 07 09 AM

It seems the jest preset is error for getBaseWebPreset, since the jest-preset is removed from the latest react-native-web (0.18.xx). Reference: necolas/react-native-web#2312

Do you guys have any idea on how to fix the jest-preset? @ikusa @darcien

@StefanusChristian
Copy link
Contributor Author

StefanusChristian commented Feb 10, 2023

@ikusa @darcien
Web jest & test finally adjusted 🎉🎉🎉

Passed Tests
Passed.exoflex.test.mp4

I'll list the changes for making the web test work in here:

  1. Adjust the getBaseWebPreset (web platform jest-preset) to use module mapper based on latest rnw docs and set testEnvironment to jsdom for web.
  2. Upgrade @testing-library/react & react-dom to match our current react version.
  3. Add testID on some component that will turn into data-testid when rendered on our web test. Reference.
  4. Adjust function from @testing-library/react: wait into waitFor and fireEvent.click usage. For fireEvent adjustment, somehow the fireEvent.click call doesn't trigger the mock function, so I use below form instead and it works. This might need more time to investigate but I think the adjustment is good for now
From:

fireEvent.click(getByTestId('button'));

Into:

fireEvent(
  getByTestId('button'),
  new MouseEvent('click', {
    bubbles: true,
    cancelable: true,
  }),
);

Copy link
Contributor

@ikusa ikusa left a comment

Choose a reason for hiding this comment

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

Let's merge this

@ikusa ikusa merged commit 173a951 into kodefox:master Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants