diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000..d63e8e5 Binary files /dev/null and b/docs/assets/favicon.png differ diff --git a/docs/assets/logo.png b/docs/assets/logo.png new file mode 100644 index 0000000..7661493 Binary files /dev/null and b/docs/assets/logo.png differ diff --git a/docs/commands/add/notifications.md b/docs/commands/add/notifications.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/commands/index.md b/docs/commands/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/core/eslint.md b/docs/core/eslint.md new file mode 100644 index 0000000..95d6579 --- /dev/null +++ b/docs/core/eslint.md @@ -0,0 +1,58 @@ +Belt comes pre-configured with [thoughtbot’s ESLint and Prettier setups](https://github.com/thoughtbot/eslint-config) to enforce best practices and maintain code consistency across your React Native projects. These tools work together to ensure that your code is not only functional but also clean, readable, and maintainable. + +## ESLint Configuration + +Belt uses thoughtbot’s sharable ESLint configuration, which includes setups for React, React Native, TypeScript, and Web in general. These configurations are designed to enforce thoughtbot’s [JavaScript style guide](https://github.com/thoughtbot/eslint-config?tab=readme-ov-file1) while being largely compatible with the popular ESLint config. + +When you start a new project with Belt, the appropriate ESLint configuration is automatically applied based on the project type. For example: + +- **React Native Projects**: Belt applies the `@thoughtbot/eslint-config/native` configuration, which includes rules and plugins tailored for React Native development. +- **TypeScript Support**: If your project uses TypeScript, Belt also applies the `@thoughtbot/eslint-config/typescript` configuration, adding rules specific to TypeScript. + +The configurations that include Prettier automatically disable ESLint rules that are handled by Prettier, ensuring that there are no conflicts between the two tools. + +## Prettier Integration + +Prettier is integrated with ESLint in Belt to manage code formatting. By default, Prettier is configured to enforce thoughtbot’s formatting guidelines, such as: + +- **Single Quotes**: Prettier is configured to prefer single quotes over double quotes. +- **Semicolons**: Enforces the use of semicolons at the end of each statement. +- **Trailing Commas**: Adds a trailing comma after each item in a multi-line array or object literal, including the last item. + +## Customization + +The ESLint and Prettier configurations are ready to use as soon as you create a new project with Belt. However, if you wish to modify or extend the default setup, you can do so by editing the `.eslintrc.js` and `.prettierrc` files in your project’s root directory. For example: + +- **React Native with TypeScript**: + ```json + { + "extends": [ + "@thoughtbot/eslint-config/native", + "@thoughtbot/eslint-config/typescript" + ] + } + ``` + +- **Custom Rule Overrides**: + You can override any of the shared rules by adding your own rules within the `rules` property: + ```json + { + "extends": "@thoughtbot/eslint-config", + "rules": { + "react/jsx-newline": "warn" + } + } + ``` + +## Troubleshooting +If you encounter issues with Jest not detecting the version, you may need to add the following to your ESLint config: + +```json +{ + "settings": { + "jest": { + "version": "detect" + } + } +} +``` diff --git a/docs/core/expo.md b/docs/core/expo.md new file mode 100644 index 0000000..7df85dd --- /dev/null +++ b/docs/core/expo.md @@ -0,0 +1,38 @@ +### Using Expo with Belt + +Belt leverages Expo to provide a streamlined and efficient development experience for React Native apps. It is a powerful platform that simplifies the process of building, deploying, and managing React Native applications. + +#### Why Expo? + +Expo is the recommended choice for React Native development due to its: + +- **Ease of Use**: Expo abstracts away much of the complexity involved in setting up and managing a React Native app, making it easier for developers to get started and stay productive. +- **Pre-Built Components**: It comes packed with a rich set of pre-built components and APIs that simplify common tasks such as accessing device features, managing media, and integrating with third-party services. +- **Facilitated Distribution**: Expo simplifies the distribution process by providing tools and services that make it easy to build, deploy, and update your app across both iOS and Android platforms. +- **Over-the-Air Updates**: After the app is published, you can push updates directly to users without requiring them to download a new version from the app store. This also allow you to quickly roll out hotfixes to all users. + +#### How Belt Configures Expo + +When you create a new app with Belt, it automatically configures Expo with the latest stable version, tested and integrated with all the additional features included in Belt. It uses Expo’s managed workflow, which handles most of the heavy lifting related to native code. This means you can build your app without needing to touch Xcode or Android Studio unless you choose to eject. Additionally, it facilitates internal sharing of the app with your team, making it easy to distribute and test new builds with stakeholders. + +#### Customizing Expo in Your Belt App + +While Belt provides a solid foundation with Expo, you have the flexibility to customize and extend the Expo setup as needed. You can modify the `app.json` file to adjust settings, add new Expo modules, or configure additional plugins specific to your app's requirements. + +Additionally, if your project outgrows the managed workflow, you have the option to eject from Expo, giving you full control over the native code. This is a more advanced option and is generally not needed unless you require custom native modules or other platform-specific customizations. + +#### Working with Expo CLI + +Belt includes commands that integrate seamlessly with Expo CLI, allowing you to manage your app's lifecycle easily. + +```bash +# Start the development server +yarn start + +# Run the app on an iOS or Android simulator +yarn ios +yarn android + +# Build the app for production +yarn build +``` diff --git a/docs/core/navigation.md b/docs/core/navigation.md new file mode 100644 index 0000000..9c022f9 --- /dev/null +++ b/docs/core/navigation.md @@ -0,0 +1,129 @@ +# Setting Up Navigation with Belt + +When you generate a new React Native project using Belt, it automatically sets up navigation to ensure you have a robust and scalable navigation structure out of the box. Here’s how Belt configures navigation for your project: + +## Installation + +Belt installs the necessary dependencies for navigation, including React Navigation and related libraries. The following packages are added to your project: + +- `@react-navigation/native` +- `@react-navigation/bottom-tabs` +- `@react-navigation/native-stack` +- `react-native-screens` +- `react-native-safe-area-context` + +## Configuration + +Belt configures navigation with sensible defaults to get you started quickly. Here’s what Belt sets up: + +### Navigation Container +The `NavigationContainer` is set up in the main application component to manage the navigation tree and state. It is injected in the list of providers in order to wrap other components under the navigation structure. For instance: + + ```tsx + import { NavigationContainer } from '@react-navigation/native'; + import Providers, { Provider } from 'src/components/Providers'; + import RootNavigator from 'src/navigators/RootNavigator'; + import queryClient from 'src/util/api/queryClient'; + + const providers: Provider[] = [ + (children) => {children}, + // CODEGEN:BELT:PROVIDERS - do not remove + ]; + + export default function App() { + // CODEGEN:BELT:HOOKS - do not remove + return ( + + + + ); + } + ``` +The order of providers added in the `Providers` array will matter, as they are wrapped in reverse order from the array. + +### Root Navigator +The RootNavigator is a central component in the navigation structure of your application. It defines the main navigation stack and serves as the entry point for all other navigators and screens. + +```tsx +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import HomeScreen from 'src/screens/HomeScreen'; +import AboutScreen from 'src/screens/AboutScreen'; + +const Stack = createNativeStackNavigator(); + +export default function RootNavigator() { + return ( + + + + + ); +} +``` + +## Setting Up Navigator Types with Belt + +Belt ensures that your navigation structure is strongly typed by setting up TypeScript types for all navigators and screens. This helps catch errors at compile time and provides better IntelliSense support in your IDE. The types for each navigator are declared in a dedicated file, named `navigatorTypes.tsx`, including type definitions for the root stack, tabs, and individual screens. + +### Using Navigator Types + +These types are then used throughout the application to ensure type safety. For example, when defining a stack navigator, you can specify the type for the navigator and its screens: + +Example: `DashboardStack.tsx` + +```tsx +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import React from 'react'; +import HomeScreen from '../screens/HomeScreen/HomeScreen'; +import InformationScreen from '../screens/InformationScreen/InformationScreen'; +import { DashboardTabParamList } from './navigatorTypes'; + +const Dashboard = createNativeStackNavigator(); + +export default function DashboardStack() { + return ( + + + + + ); +} +``` + +### Benefits of Typed Navigation + +1. **Compile-Time Safety**: TypeScript will catch errors related to navigation at compile time, reducing runtime errors. +2. **IntelliSense Support**: IDEs like Visual Studio Code provide better auto-completion and documentation support when types are defined. +3. **Documentation**: Types serve as a form of documentation, making it easier for developers to understand the navigation structure. + +By setting up navigator types, your navigation code is robust, maintainable, and easy to understand. + +## Testing Navigation + +Belt also sets up testing utilities to help you test navigation flows. You can use the `renderApplication` utility to render the entire app with navigation ready for integration tests. + +Example: `App.integration.test.tsx` + +```tsx +import { screen, userEvent } from '@testing-library/react-native'; +import { renderApplication } from 'src/test/render'; + +test('renders app, can navigate between screens', async () => { + renderApplication(); + + expect( + await screen.findByText('Welcome to the Home Screen'), + ).toBeDefined(); + + await userEvent.press(screen.getByText('Go to About')); + expect( + await screen.findByText('Welcome to the About Screen'), + ).toBeDefined(); +}); +``` + +As your app development progresses this will give you fine-grain control over simulating specific application states and context. diff --git a/docs/core/query.md b/docs/core/query.md new file mode 100644 index 0000000..0deee3b --- /dev/null +++ b/docs/core/query.md @@ -0,0 +1,72 @@ +# Setting Up TanStack Query with Belt + +When you create a new project with Belt, [TanStack Query](https://tanstack.com/query/latest) (formerly known as React Query) is automatically set up to manage server-state in your React Native application. This setup ensures you have a robust and scalable solution for data fetching, caching, synchronization, and more. + +## Installation + +Belt installs the necessary dependencies for TanStack Query. The following packages are added to your project: + +- `@tanstack/react-query` +- `@tanstack/react-query-devtools` + +These dependencies are included in your `package.json` file and installed during the project creation process. + +## Configuration + +### Query Client + +A `queryClient` instance is created and configured in the `queryClient.ts` file with a basic configuration. Retry logic is disabled by default but you can customize it based on your application and back-end behavior. + +```tsx +import { QueryClient } from '@tanstack/react-query'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}); + +export default queryClient; +``` + +### Query Client Provider + +The `QueryClientProvider` is set up in the main application component to provide the query client to the entire app. This is done in the `App.tsx` file: + +```tsx +import { QueryClientProvider } from '@tanstack/react-query'; +import Providers, { Provider } from 'src/components/Providers'; +import RootNavigator from 'src/navigators/RootNavigator'; +import queryClient from 'src/util/api/queryClient'; + +const providers: Provider[] = [ + (children) => ( + {children} + ), + // CODEGEN:BELT:PROVIDERS - do not remove +]; + +export default function App() { + // CODEGEN:BELT:HOOKS - do not remove + return ( + + + + ); +} +``` + +To demonstrate how to use TanStack Query in your project, Belt includes an example in the `AboutScreen.tsx` file: + +## Benefits of Using TanStack Query + +1. **Automatic Caching**: TanStack Query automatically caches query results, reducing the need for manual state management. +2. **Background Updates**: Queries can be configured to refetch in the background, ensuring your data is always up-to-date. +3. **Optimistic Updates**: TanStack Query supports optimistic updates, providing a smoother user experience by updating the UI before the server responds. +4. **Error Handling**: Built-in error handling mechanisms make it easier to manage and display errors in your application. + +## Customization + +The default configuration provided by Belt is designed to meet the needs of most React Native projects, but it can be customized as needed. You can modify the `queryClient` configuration in the `queryClient.ts` file to adjust default options, retry logic, caching and other settings to better fit your project. diff --git a/docs/core/testing.md b/docs/core/testing.md new file mode 100644 index 0000000..ddc8692 --- /dev/null +++ b/docs/core/testing.md @@ -0,0 +1,45 @@ +## Setting Up Testing Library with Belt + +When you generate a new React Native project using Belt, it automatically sets up the Testing Library to ensure you have a robust testing environment out of the box. Here’s how Belt configures the Testing Library for your project: + +### Installation + +Belt installs the necessary dependencies for the Testing Library, including Jest and related testing utilities. The following packages are added to your project: + +- `@testing-library/react-native` +- `@testing-library/jest-native` +- `jest` +- `babel-jest` +- `@types/jest` + +### Configuration + +Belt configures Jest and the Testing Library with sensible defaults to get you started quickly. Here’s what Belt sets up: + +- **Jest Configuration**: A pre-configured `jest.config.js` file is added to your project. This configuration includes settings tailored for React Native and Expo. + +- **Setup File**: A `jest.setup.js` file is included to configure the testing environment. This file sets up mocks and other configurations needed for testing. Here's a breakdown of what it sets up: + + - Safe Area Context: mock the Safe Area Context to avoid issues related to safe area insets during testing. + - BackHandler: mock the BackHandler to control back button behavior in tests. + - Expo Modules: handle Expo-specific modules to avoid issues related to fonts and assets during testing. + - Mock Service Worker (MSW) Server: sets up a MSW server to intercept network requests during tests, allowing you to mock API responses. + - Query Client: clears the query client to ensure no stale data is carried over between tests. + - Debug Output: customizes the debug output of Testing Library to include only common props that might affect test failures, reducing verbosity. + +- **Testing Utilities**: Belt includes utility functions like `renderApplication` to simplify rendering components with the necessary providers and mocks. + +### Running Tests + +You can run these scripts using your package manager: + +```sh +# Run tests +npm test + +# Run tests with coverage +npm run test:cov + +# Run all tests and linting +npm run test:all +``` diff --git a/docs/core/typescript.md b/docs/core/typescript.md new file mode 100644 index 0000000..50238e6 --- /dev/null +++ b/docs/core/typescript.md @@ -0,0 +1,15 @@ +## TypeScript Configuration Overview + +When you create a new project with Belt, a pre-configured `tsconfig.json` file is automatically added to your project’s root directory. This configuration provides a solid foundation for using TypeScript in React Native, with settings that focus on improving code quality and catching errors early. This is a list of belt specific configurations: + +- **Strict Type-Checking**: enforces strict type-checking (`strict: true`) to catch potential issues early. +- **Force Consistent Casing**: adds `forceConsistentCasingInFileNames: true` to ensure consistent file naming across the project. +- **Custom Module Paths**: defines paths for `src/*` and `assets/*`, making imports more convenient. +- **Expanded Inclusions**: includes additional file types in the include section (`*.js`, `.*.js`, `__mocks__`). +- **No Fallthrough in Switch Cases**: includes `noFallthroughCasesInSwitch: true` to prevent errors in switch statements. + +Additionally, Belt extends the TypeScript configuration with `expo/tsconfig.base`, maintaining full compatibility with Expo’s managed workflow. + +## Customizing TypeScript in Your Project + +The default TypeScript configuration in Belt is designed to meet the needs of most React Native projects, but it can be customized as needed. You can modify the `tsconfig.json` file to adjust compiler options, module resolution paths, or other settings to better fit your project. diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md new file mode 100644 index 0000000..8d428b3 --- /dev/null +++ b/docs/getting_started/installation.md @@ -0,0 +1,46 @@ +# Creating a new app + +## System Requirements +- Node.js 18.18 or later + +## Quick Start + +To quickly set up a new React Native app using Belt, run the following command in your terminal: + +```sh +# With NPM +npx create-belt-app MyApp +``` + +If you prefer you can also create a Belt app with Yarn, pnpm, or Bun by running the corresponding commands: + +```sh +# With Yarn +npx create-belt-app MyApp --yarn + +# With pnpm (experimental) +npx create-belt-app MyApp --pnpm + +# With Bun (experimental) +npx create-belt-app MyApp --bun +``` + +You will be prompted to confirm the app details and all the tools that will be setup, then Belt will generate the new app using Expo, install all the necessary dependencies and run an initial set of tests. + +## Extending App Functionality + +After creating a project with Belt, the tool adds handles that allow you to extend your app’s functionality with minimal effort. For instance, if you want to add Push Notification capability, run the following command and follow the instructions: + +```sh +# With Yarn +yarn belt add notifications + +# With NPM +npx belt add notifications + +# With PNPM +pnpm belt add notifications +``` +The above will inject the necessary code and install required dependencies to get notifications displaying in your app. All you need to do is handle the setup outside of the code, like configuring the notification service, and you’re good to go. + +If you'd like to know more details about how extending your app functionality's work, please refer to the [commands](../commands) section. diff --git a/docs/getting_started/overview.md b/docs/getting_started/overview.md new file mode 100644 index 0000000..f522ce9 --- /dev/null +++ b/docs/getting_started/overview.md @@ -0,0 +1,20 @@ +!!! info + While we actively use Belt internally at thoughtbot, this project is still in early phases of development, so its API might still change frequently. + + +# Overview + +Belt is an opinionated CLI tool for starting a new React Native app. Developed and actively used by the mobile team at thoughtbot, Belt is designed to simplify the setup process by making many of the standard decisions for you, based on tooling and conventions that have been battle-tested through numerous successful projects. + +By using Belt, you can quickly scaffold a new React Native app with a pre-configured setup that includes a curated selection of tools and libraries: + +- **Expo** for rapid development and deployment. +- **ESLint** and **Prettier** for consistent code style. +- **TypeScript** for type safety. +- **Jest** and **React Native Testing Library** for testing. +- **MSW** for API mocking during development. +- **React Navigation** with bottom tabs for navigation structure. +- **Tanstack Query** for REST API integration (with Apollo Client for GraphQL and Redux Toolkit for global state management coming soon). + + +Additionally, Belt is designed to be flexible — the default setup can be customized as your project evolves, allowing you to adapt configurations and tooling to best fit your needs. New features can also be added independently using standalone commands, giving you full control over your development environment. diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..585071e --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,103 @@ +site_name: Belt +site_url: https://mydomain.org/belt +site_author: Diego Oliveira +site_description: >- + Discover Belt, thoughtbot’s new CLI tool that simplifies starting React Native apps with smart defaults and easy feature integration. Perfect for developers looking to streamline their workflow. + +repo_name: thoughtbot/belt +repo_url: https://github.com/thoughtbot/belt + +copyright: Copyright © 2024 thoughtbot + +theme: + name: material + # custom_dir: overrides + features: + - header.autohide + - navigation.footer + - navigation.path + - toc.follow + - navigation.sections + - navigation.instant + logo: assets/logo.png + favicon: assets/favicon.png + +# extra_css: +# - stylesheets/extra.css +extra: + social: + - icon: fontawesome/brands/mastodon + link: https://thoughtbot.social/public/local + - icon: fontawesome/brands/github + link: https://github.com/thoughtbot + - icon: fontawesome/brands/twitter + link: https://twitter.com/thoughtbot?lang=en + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/company/thoughtbot-inc-/posts/?feedView=all + - icon: fontawesome/brands/instagram + link: https://www.instagram.com/thoughtbot/?hl=en + +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - toc: + permalink: true + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + normalize_issue_symbols: true + repo_url_shorthand: true + user: squidfunk + repo: mkdocs-material + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.snippets: + auto_append: + - includes/mkdocs.md + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + combine_header_slug: true + slugify: !!python/object/apply:pymdownx.slugs.slugify + kwds: + case: lower + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + +not_in_nav: | + /tutorials/**/*.md + +# Page tree +nav: + - Getting Started: + - Overview: getting_started/overview.md + - Creating a new app with Belt: getting_started/installation.md + - Core Features: + - Expo: core/expo.md + - ESLint and Prettier: core/eslint.md + - TypeScript: core/typescript.md + - Testing: core/testing.md + - Navigation: core/navigation.md + - Data Management: core/query.md