The Google Summer of Code 2021 has been a fantastic and cheerful learning experience for me over the past few months. I have learned a lot from the community, especially how to organize commits and write readable code. React Native Elements is an amazing community to work with, as mentors are really helpful and experienced. I had started contributing to React Native Elements from March 2021 and till now, I have 40+ commits (10,803 additions and 13,826 deletions) merged. Over the past few months, I had great exposure writing maintainable code, communicating with the mentors, etc. I had completed some of my work in the coding period started as some issues mentioned in my proposal had a high priority for the release.
Pressable is preferred to Touchable components according to React Native official docs. Pressable component offers a more extensive and future-proof way of handling the touch-based inputs.
Touchable Component:
It includes the styles and effects that do not meet the platform interactions.
It does not support high-quality interaction experience on different platforms.
Pressable Component:
It detects various types of interactions.
Its API provides direct access to the current state of interaction.
Its capabilities could be extended to include hover, blur, focus, and more.
Pressable contains a lot of new props and cool features such as:
delayLongPress: Duration in milliseconds from onPressIn by the time onLongPress is called.
Migrate Tests to React Native Testing Library (#3170)#
Rather than tests focusing on the implementation (Enzyme), tests are more focused on user behavior (react-native-testing-library).
Enzyme allows us to access the internal workings of your components. You can read and set the state, and we can mock children to make tests run faster. On the other hand, RN testing-library doesn't give us any access to the implementation details. It renders the components and provides utility methods to interact with them. The idea is that you should communicate with our application in the same way a user would. So rather than set the state of a component we reproduce the actions a user would do to reach that state.
Some components like Image, ToolTip which further include SearchBar android & SearchBar iOS were Class Components and the code was messy, These are migrated to Functional Components and added hooks like, useState, useEffect, useCallBack, which would increase performance.
Using classes - We need to describe lifecycle methods, state of the component, component’s methods that will change our state or work with the store. Also, we need to bind all the methods for the component instance. The component becomes large, and it becomes more difficult to read each time.
Using hooks - We can get the state of the component so that it can be easily tested and reused. Now we can facilitate the exchange of links between components or our entire application - using hooks. Hooks allow you to encapsulate logic without affecting the hierarchy of components.
Automatically generate documentation out of React/React Native Component
This summer, I was pleased to get selected for Google Summer of Code'21 under the organization React Native Elements. Working under the organization, my project was to generate documentation automatically out of the UI components and present it in the Docusaurus website.
The purpose of creating this repository is to maintain a report summary of my GSoC work and this may also serve as a guide for future GSoC aspirants and a reference to the developers and contributors to the project.
React Native Elements is a cross-platform UI toolkit built on/for React Native. With a weekly download by 90k+ users and backed by a huge community, it provides UI components that can be used in your native application for the platform of Android/iOS/Web.
The documentation of the project was maintained manually previously i.e., suppose I want to change/add/remove a prop or a new component to the project the markdown file had to be changed manually. The process is tiring and new contributors may often forget to do so. So, during the summers I took the change this process and make a workflow such that the generation is automatic. This should be fast and maintainable.
This is a guide to generate documentation of the UI components automatically.
Initially when this workflow was not present, the entire documentation of the website was done by editing the docs manually by going to the docs directory under website and editing the markdown manually. Now, we have come with a flow where developers and contributors can focus more on logic than on writing markdown.
To do this we have created scripts which would parse the components and generate documentation out of it.
This is a 2 step process:
We take use of react-docgen-typescript which takes the input of the files for which we want to generate the documentation automatically. This gives in JSON as output. This JSON consists of all the details of the props including type, name, description and defaultValue and well as description of the components.
As we use Docusaurus for our documentation website, the pages of the documentation should be in the format of Markdown. Therefore, there should be process where we can change the JSON data, which we get from react-docgen-typescript to a suitable Markdown format. For this we use, json2md which takes in the data and convert it to suitable markdown string. This is stored in the directory and is shown on the website.
Well to make the script to work automatically what we have done is as follows:
When you push your changes to your branch. A script updateDocumentation.js runs.
This invokes the yarn docs:build command which calls the scripts of auto-generation of docs and this also lints the markdown files generated at the same time.
Now, if there is any changes in the markdown files. A commit with message Update Documentation is done and pushed after your commit is done to the branch.
Note: By passing pre-push hook will result in failure of documentation update and may lead maintainers to close your PR.
This is simple. Adding, removing, updating the props is also simple now. You just need to update the comments/description of the component and deal with the logic of your React Components(if required). Our workflow will automatically detect the markdown changes if any and push the changes using pre-push hooks while you push your code to your branch.
Trust me this is easy. We have designed the workflow such that, you only need to work on your JavaScript/TypeScript logic, without bothering about updating the markdown files. The input to the docgenParser is automatic and doesn't require any aditional cofiguration.
Make sure to add appropriate comments and description related to the components and the props of the component. Try keeping your code simple with simpler types for Autogen to work.
Please note: The file name of the component as well as the folder must be in Capital letter. We use regex to parse the file paths, so this is important.
Note: If there are complex types/defaultValue, please head to website/scripts/docgen/docgenParser.ts to deal with those cases. Although we recommend you to avoid it as far as possible. Try improving the React logic and that will work.
The demos can now be added by moving in to the usage directory under website/docs/main directory. We now have added Snack Player so that you get the glimpse of the component and also get to know how it works. Under the usage, there is a separate folder for each UI Component, where you can add Usage related to component and relevant descriptions.
Note: To add Snack demo, add it inside the snack directory. You can add as many Snack which will make our repository more helpful for developers.
For testing the changes in the documentation autogeneration, we simply need to run the following commands in sequence.
cd websiteyarntest
We have also included the changes in the main test process, so this will automatically run with the workflow as well as when you run the yarn test command from root of the project.
Some of the components are class-based. They are: Input, SearchBar, Rating.(from https://github.com/Monte9/react-native-ratings). If you change the components to Functional/hooks based please remove it from the array of filesToExclude under website/scripts/docgen/getComponentFiles.ts. These are the paths of the component files for which the process is still manual.
So, generating the documentation doesn't come up well for these components. Due to the existing structure react-docgen-typescript fails to generate relevant result for them. We are therefore looking for contributions on these components to make them Fuctional/Hooks based.
Thanks. Hope you like the new workflow. Looking forward for improvements and contributions to it.
There have been a lot of changes and improvements coming through the pipeline recently with react-native-elements. So in preparing for a version 3, there are some planned deprecations that will be added into version 2.3 and then removed in version 3.
The reason for these changes is that react-native-elements regularly gets requests for new features and enhancements quite frequently. The fast and easy method of adding these new features is usually to add another prop into the component that then injects some change into a child component. Unfortunately, this ends up leading to the components having a lot of props, lots of conditional code, and additional code complexity. The solution going forward and into version 3 will be to break down large components into smaller pieces so that it is easier to inject your own code without having to wait for an additional prop to be added.
As we continue to build up to version 3, this post will continue to be updated with new step-by-step directions on how to upgrade your code to work around these changes. The RNE team thanks you for your patience, and we hope that you see the value in the upcoming changes.
accessory, showAccessory, and accessoryProps are all being dprecated. There is now a child component Avatar.Accessory that you insert as a child component instead.
ListItem has a large number of deprecated props. ListItem has been somewhat of a kitchen sink. All the props can be replaced by inserting them as children in the order of left to right as they appear on the screen.
For Card the following props have all been deprecated: title, titleStyle, titleNumberOfLines, dividerStyle, image, imageStyle, imageProps, imageWrapperStyle, featuredTitle, featuredTitleStyle, featuredSubtitle, featuredSubtitleStyle
BottomSheet was added in version 2.2, and it was noted that it had some strict dependencies that weren't so well liked. So BottomSheet has changed completely and it is encouraged that you checkout the docs page on it again.
Make sure to checkout the customization page. We added a dark mode configuration to the ThemeProvider that should help out in bootstraping your app's dark mode.
React Native Elements has UI elements that are easy to use & really customizable. It also has theming, platform specific search bars, React Native Web support, and much more.
It's finally here! Let's put our hands together and welcome React Native Elements 1.0 🎉
This release is centered around making RNE components that everyone loves more intuitive to use & stable. This is not to say that all the work is done, but this is definitely a giant leap in the right direction and one that we have been working on for over a year.
I want like to say thank you to our users for using RNE and giving us feedback through issues on the repo and also the contributors who have the taken time to contribute and help improve RNE together. Finally, I'd like to say a big thanks to Kyle Roach and Xavier Villelégier without whom this project would not have been as awesome as it is today!!
This blog post is meant to serve as a migration guide for upgrading to react-native-elements: "^1.0.0" from 0.19.1 and also a way to document and share all the breaking changes, new features and other improvements in this release. For those updating from 1.0.0-beta7 you can view those release notes here.
The wait is over!! Get excited, cause we certainly are. 14K 🌟 and counting...
normalizeFontSize prop removed. You can use the normalize helper along with the inputStyle prop to normalize font sizes.
FormLabel has been removed. This is now built into the Input component by use of label prop. Props labelStyle and labelProps can be used to customize it.
FormValidationMessage has been removed. This is now built into the Input component by use of errorMessage prop. Props errorStyle and errorProps can be used to customize it.
Props innerContainerStyles, outerContainerStyles removed #1221. Instead use the containerStyle prop for main styling, along with props leftContainerStyle, centerContainerStyle, and rightContainerStyle when needed.
SearchBar now supports different platform styles! To get an iOS or Android themed SearchBar, use the platform prop. platform="ios" or platform="android"
noIcon prop removed. Instead to remove the search icon use the searchIcon prop. E.g searchIcon={null}
List component has been removed!List was just a regular React Native View with some small margin styles. It wasn't actually needed to use the ListItem component. Instead we recommend using the FlatList or SectionList components from React Native which function both as Views and also displaying items, pull to refresh and more.
If you want to apply the same styles that the List component provided prior to 1.0, see this comment.
avatar, avatarStyle, avatarContainerStyle, roundAvatar, and avatarOverlayContainerStyle removed. Avatars can now be customized using the rightAvatar and leftAvatar props which can either render a custom element or an object that describes the props from Avatar.
wrapperStyle prop removed. Use the containerStyle prop instead.
titleNumberOfLines, subtitleNumberOfLines, and rightTitleNumberOfLines props removed. Use the titleProps, rightTitleProps, and subtitleProps props to pass props for each..
<ListItemtitleProps={{ numberOfLines:4}}/>
hideChevron removed. Use the chevron prop instead. However, the behaviour is swapped hideChevron={true} behaves like chevron={false}
chevronColor removed. The chevron prop now can accept an object describing it's appearance.
<ListItemchevron={{ color:'pink'}}/>
fontFamily removed. Use the titleStyle and subTitleStyle props to set change the text styling
titleContainerStyle removed. Use the titleStyle prop instead.
rightTitleContainerStyle removed. Use the rightTitleStyle prop instead.
subtitleContainerStyle removed. Use the subtitleStyle prop instead.
label prop removed.
switchButton, onSwitch, switchDisabled, switchOnTintColor, switchThumbTintColor, switchTintColor, and switched removed. Instead use the switch prop wich accepts an object describing its props.
textInput,textInputAutoCapitalize,textInputAutoCorrect,textInputAutoFocus,textInputEditable,textInputKeyboardType,textInputMaxLength,textInputMultiline,textInputOnChangeText,textInputOnFocus,textInputOnBlur,textInputSelectTextOnFocus,textInputReturnKeyType,textInputValue,textInputSecure,textInputStyle,textInputContainerStyle,textInputPlaceholder removed. We now expose a single input prop which accepts an object describing its props.
onPressRightIcon removed. Use the rightIcon prop which can accept an object now describing its props.
λ create-react-native-web-app gitphone⏳ Creating React Native Web App by the name of gitphone ...✅ Created project folder.✅ Added project files.⏳ Installing project dependencies...yarn install v1.10.1[1/4] Resolving packages...[2/4] Fetching packages...info fsevents@1.2.4: The platform "win32" is incompatible with this module.info "fsevents@1.2.4" is an optional dependency and failed compatibility check. Excluding it from installation.[3/4] Linking dependencies...[4/4] Building fresh packages...success Saved lockfile.Done in 797.66s.✅ Installed project dependencies.✅ Done! 😁👍 Your project is ready for development.* change directory to your new project$ cd gitphone$ Then run the these commands to get started:* To run development Web server$ yarn web* To run Android on connected device (after installing Android Debug Bridge "adb" - https://developer.android.com/studio/releases/platform-tools)$ yarn android* To run ios simulator (after installing Xcode - only on Apple devices)$ yarn ios* To run tests for Native and Web$ yarn test* To run build for Web$ yarn build
Change to gitphone directory and test the web app by running yarn web.
Starting the development server...Compiled successfully!You can now view create-react-native-web-app in the browser.Local: http://localhost:3001/On Your Network: http://172.26.235.145:3001/Note that the development build is not optimized.To create a production build, use yarn build.
Now, test the gitphone android app by running yarn android.
Installing APK 'app-debug.apk' on 'Redmi 4X - 7.1.2' for app:debugInstalled on 1 device.BUILD SUCCESSFULTotal time: 21.783 secsStarting: Intent { cmp=com.creaternwapp/.MainActivity }✨ Done in 25.64s.
If the build successful, you'll see the app installed on your Android (emulator) device.
But if you got an error when run yarn android, please see Troubleshooting section below.
The last part for First Step, make sure it can be run on iOS without any problem. Run yarn ios and voila!
Both RNE and RNVI are written using es6. If you run yarn web at this point, you'll got an error.
./node_modules/react-native-elements/src/config/withTheme.jsModule parse failed: Unexpected token (12:28)You may need an appropriate loader to handle this file type.
We need to tell webpack to transpile them.
Open config/webpack.config.dev.js
On line 141 Process JS with babel, add RNE and RNVI to include
Do the same for config/webpack.config.prod.js as well 👌
Let’s fetch a real-live data: list commit on repository by GitHub and render it on our second screen, CommitList.
GET /repos/:owner/:repo/commits
Ideally, the :owner and :repo are form values from our first screen. Since the objective of this article is RNE x RNW, talk about that form (and state-management) later on.
To fetch GitHub API, we will use fetch-hoc package and also need compose from redux, to handle multiple HOCs on the same component.
$ yarn add fetch-hoc redux
Open CommitList.js
Import { compose } from redux and fetch from fetch-hoc
If you go back from Commits screen, input form on Home screen are empty. If you want preserve previous values, this can be fixed easily by introducing redux to the app. References here: 48108dd.
Can we fetch more commits data once we reach the most bottom of the list? Infinite scroll?
:app:compileDebugAidl FAILEDFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':app:compileDebugAidl'.> java.lang.IllegalStateException: aidl is missing* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.BUILD FAILED
Here is how to fix #1:
Open Android Studio.
Open android project under gitphone.
Click Update on this prompt.
Wait for Android Studio syncing the project.
It synced successfully with two errors.
At this stage, just click Update Build Tools version and sync project on the sync window.
Now, the remaining warning is the Configuration 'compile'...
To fix that, open app/build.gradle file, change dependencies section (line 139) to use implementation instead of compile.
Troubleshooting for android is done. Now, you should be able to run yarn android successfully.
#2 Build failed when running yarn ios
** BUILD FAILED **The following build commands failed: CompileC /gitphone/ios/build/Build/Intermediates.noindex/React.build/Debug-iphonesimulator/double-conversion.build/Objects-normal/x86_64/strtod.o /gitphone/node_modules/react-native/third-party/double-conversion-1.1.5/src/strtod.cc normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
Here is how to fix #2:
Inside the project, run script below from your favourite terminal
$ curl -L https://git.io/fix-rn-xcode10 | bash
If you run yarn ios again, and you got this error
The following build commands failed: Libtool /gitphone/ios/build/Build/Products/Debug-iphonesimulator/libRCTWebSocket.a normal x86_64(1 failure)