io-app
io-app copied to clipboard
chore(Cross): [IOAPPX-356] Add divider to first level sections when the user scrolls
[!note] This change applies only to the Wallet (new), Services, Payments and Profile sections.
Short description
This PR adds the new divider transition to first level sections when the user scrolls. To get this behaviour, we need to define HeaderFirstLevelProps directly in the main screen through useLayoutEffect where the main ScrollView or FlatList is placed.
To avoid code duplication, there's a new useHeaderFirstLevelActionPropHelp's hook that returns a FAQ configuration object based on the provided route.
List of changes proposed in this pull request
- Add the new divider transition to the
HeaderFirstLevelusing theuseScrollViewOffsethook fromreanimated - Add the new optional
endBlockprop toHeaderFirstLevelto render custom block (~~see the Services screen for a demonstration~~ update: removed from the branch) - Migrate the header configuration from the
HeaderFirstLevelHandlerto relative first-level sections - Replace
GradientScrollViewwithIOScrollViewin the new Wallet home screen, adding dark mode support in the process (cc @mastro993) - Add quick scroll to top to the new Wallet home screen when the user taps on the active tab item, like other sections (cc @mastro993)
- Add the new
useHeaderFirstLevelActionPropHelphook - For testing purposes, update
HeaderFirstLevelwith the latest changes fromio-app-design-system. Before merging this PR we'll also update the component in theio-app-design-system
Preview
[!important] The divider is set with
hairlineWidth, so it's very thin. If you want to see the change, download the following videos and play them at full size
| Wallet | Services | Profile |
|---|---|---|
How to test
Go to the above sections and check that everything is correct. Also check the relative flow of the Assistance in each first level section.
Affected stories
- ⚙️ IOAPPX-356: [io-app] Aggiunta del divisore quando l'utente scorre nelle sezioni di primo livello
subtask of
- ⚡ IOAPPX-32: Design System
Generated by :no_entry_sign: dangerJS against 33db7fcce08846862468d616c73f2c06a4c95753
In the services screen, I cannot reproduce the behavior that I see in the preview videos. The search bar is not sticky.
https://github.com/user-attachments/assets/711c06f4-655f-4afd-ad36-d77254db9a55
In the services screen, I cannot reproduce the behavior that I see in the preview videos. The search bar is not sticky.
@mastro993 That's because we got rid of the sticky behavior (removed in the following commit → https://github.com/pagopa/io-app/pull/6054/commits/eff2bd1cae3c90f100e985e5d8b39145180177ad)
This pull request is stale because it has been open for 60 days with no activity. If the pull request is still valid, please update it within 14 days to keep it open or merge it, otherwise it will be closed automatically.
Codecov Report
Attention: Patch coverage is 57.40741% with 46 lines in your changes missing coverage. Please review.
Project coverage is 49.31%. Comparing base (
4f204b4) to head (33db7fc). Report is 876 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #6054 +/- ##
==========================================
+ Coverage 48.42% 49.31% +0.89%
==========================================
Files 1488 1552 +64
Lines 31617 31971 +354
Branches 7669 7233 -436
==========================================
+ Hits 15311 15767 +456
+ Misses 16238 16165 -73
+ Partials 68 39 -29
| Files with missing lines | Coverage Δ | |
|---|---|---|
| ts/components/ui/IOScrollView.tsx | 87.17% <ø> (ø) |
|
| ts/features/design-system/navigation/navigator.tsx | 13.63% <ø> (-9.23%) |
:arrow_down: |
| ...tures/payments/home/screens/PaymentsHomeScreen.tsx | 78.43% <100.00%> (-16.02%) |
:arrow_down: |
| ts/hooks/useHeaderFirstLevel.tsx | 100.00% <100.00%> (ø) |
|
| ts/hooks/useHeaderFirstLevelActionPropHelp.ts | 100.00% <100.00%> (ø) |
|
| ts/hooks/useTabItemPressWhenScreenActive.tsx | 71.42% <ø> (-14.29%) |
:arrow_down: |
| ts/navigation/TabNavigator.tsx | 15.00% <ø> (+4.18%) |
:arrow_up: |
| ts/screens/profile/DeveloperModeSection.tsx | 25.19% <ø> (+20.71%) |
:arrow_up: |
| ts/screens/profile/ProfileMainScreen.tsx | 62.71% <ø> (+51.80%) |
:arrow_up: |
| ts/components/ui/HeaderFirstLevel.tsx | 96.00% <95.00%> (+66.00%) |
:arrow_up: |
| ... and 7 more |
... and 1710 files with indirect coverage changes
Continue to review full report in Codecov by Sentry.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 255c644...33db7fc. Read the comment docs.
@mastro993 @Hantex9 @Vangaorth Just updated the PR with the latest changes since this summer. I've also updated the PR description with new videos. No logic has changed, just moved elsewhere. Please check that there are no regressions with Settings and Help.
I'm curious, why not just put the logic in an Header component and returning it on top on the render function of the screen component? You're still writing a header component. You're still calling it with props. But instead of returning it where it logically belongs in the screen tree, you're shoving it into the navigator via a side effect 🤔. What's convenient in this approach?
@VariabileAleatoria Thanks for your comment. Can you please elaborate by providing a basic structure of the code you would expect?
@VariabileAleatoria Thanks for your comment. Can you please elaborate by providing a basic structure of the code you would expect?
I mean having something similar to
export const MyScreen = () => {
return (
<View style={{ flex: 1 }}>
<Header
currentRoute={}
headerProps={}
/>
{/* rest of your screen */}
</View>
);
};
With Header component having inside the same logic of the current hook, but returning JSX instead of setting the header through navigator.setOptions({header: ...})
Is there any actually benefit to defer the rendering of the custom header to react-navigation vs having it rendered with the screen?
With Header component having inside the same logic of the current hook, but returning JSX instead of setting the header through navigator.setOptions({header: ...}) Is there any actually benefit to defer the rendering of the custom header to react-navigation vs having it rendered with the screen?
OK, now I get it. What you described was the code architecture before our partial adoption of the react-navigation library. Setting the header with this library is just a more robust way of managing the way screens are rendered.
Now when you define a screen with Stack.Screen, you just pass the content to render, header aside. Before you had to include the header, but some screens got one and some didn't. It was quite messy.
Now you can programmatically hide the header when not needed at Navigator level. Or you can easily manage the back behaviour. Furthermore, if you want to migrate to the native navigation APIs, you can move from JS-based navigation to native without too much headache, as title and other navigation config props are shared.
With Header component having inside the same logic of the current hook, but returning JSX instead of setting the header through navigator.setOptions({header: ...}) Is there any actually benefit to defer the rendering of the custom header to react-navigation vs having it rendered with the screen?
OK, now I get it. What you described was the code architecture before our partial adoption of the
react-navigationlibrary. Setting the header with this library is just a more robust way of managing the way screens are rendered. Now when you define a screen withStack.Screen, you just pass the content to render, header aside. Before you had to include the header, but some screens got one and some didn't. It was quite messy.Now you can programmatically hide the header when not needed at
Navigatorlevel. Or you can easily manage the back behaviour. Furthermore, if you want to migrate to the native navigation APIs, you can move from JS-based navigation to native without too much headache, astitleand other navigation config props are shared.
To be honest I can't see much difference between hiding it with a Navigator property (headerShown: false) vs not including it in the render function 🤔
To be honest I can't see much difference between hiding it with a Navigator property (headerShown: false) vs not including it in the render function 🤔
It depends on how big your project is. What might seem like a small thing to do on your own might have a big effect on the whole team.
I've just mentioned a few of the advantages of the library, not all of them.