react-native-boilerplate Documentation

A React Native template for building solid applications ๐Ÿ™, using JavaScript ๐Ÿ’› or Typescript ๐Ÿ’™ (you choose).

RAW Doc

File: README.md

TheCodingMachine React Native boilerplate

This project is a React Native boilerplate that can be used to kickstart a mobile application.

The boilerplate provides an optimized architecture for building solid cross-platform mobile applications through separation of concerns between the UI and business logic. It is fully documented so that each piece of code that lands in your application can be understood and used.

text
If you love this boilerplate, give us a star, you will be a ray of sunshine in our lives :)

Requirements

Node 18 or greater is required. Development for iOS requires a Mac and Xcode 10 or up, and will target iOS 11 and up.

You also need to install the dependencies required by React Native.
Go to the React Native environment setup, then select React Native CLI Quickstart tab.
Follow instructions for your given development OS and target OS.

Quick start

To create a new project using the boilerplate simply run :

text
npx @react-native-community/cli@latest init MyApp --template @thecodingmachine/react-native-boilerplate

Assuming you have all the requirements installed, you can run the project by running:

  • yarn start to start the metro bundler, in a dedicated terminal
  • yarn to run the platform application (remember to start a simulator or connect a device)

Digging Deeper

To learn more about this boilerplate, go to full documentation

License

This project is released under the MIT License.

About us

TheCodingMachine is a web and mobile agency based in Paris and Lyon, France. We are constantly looking for new developers and team leaders and we love working with freelancers. You'll find an overview of all our open source projects on our website and on Github.


File: documentation/blog/2020-04-19-React-Native-Boilerplate-3.0.0.md


title: React Native Boilerplate 3.0.0 authors: jed hide_table_of_contents: false tags: [boilerplate, starter-kit, starter, kit, react, native, react-native, javascript, typescript]

Welcome aboard! ๐Ÿ›ฅ๏ธ

As we have active users that uses this boilerplate, we will try to improve communication about updates
we're releasing. It's important for us to give you new reasons to try this boilerplate out!
We would love to have new ideas to make it even more convenient!

To do so, we will post a changelog every major updates. Unlike the changelog in the releases tab, we
will here provide more details and maybe some examples.

In this first post, we will present the current state of this boilerplate.

Light ๐Ÿชถ Simple ๐Ÿ‘Œ and Scalable ๐Ÿ“

This boilerplate is the core of every react-native applications we develop at TheCodingMachine.
This means that we are the first users! If an issue appear we are the first affected ๐Ÿฅบ, that's why this project is actively maintained!

The main idea behind this boilerplate is to have just the necessary and well-known stuff to have a very
"easy to use" boilerplate for little and big real world apps.

We don't include components libraries, we don't depend on third-party libraries (like Firebase for example).
It's just a good template project that is build on top of all the accumulated experience of our mobile teams.
It also provides a solid architecture that facilitates separation of concerns between the UI, the state management
and the business logic.
Like that, everyone can add its own touch! ๐Ÿ–Œ๏ธ

๐Ÿšจ Every decision about the technical stack are made regarding our preferences (every library has his
pros and cons).

Easy to install ๐Ÿ˜Ž

Installation has been facilitated since the v2.0.0, thanks to the use of the react-native-cli and
custom template.
To run this boilerplate, the only commands you need are

text
npx react-native init --template @thecodingmachine/react-native-boilerplate
yarn start
yarn ios
yarn android

That's this simple! ๐Ÿš€

Typescript support ๐Ÿ’™

Since the v3.0.0, during the installation, you can choose to use typescript for your new app.
All the boilerplate will then be translated in typescript.

That's this simple! ๐Ÿš€

Solid libraries ๐Ÿ”จ

As I said before, main concerns are simplicity and scalability.
Each of the used libraries are well-known, tried and tested.

Well-know libraries

For the state management we use Redux (redux + redux toolkit + redux persist).
Some people like it, some people don't.
We are really comfortable with this library, it's not so difficult to learn, and the implementation is well-known,
recognized as a good choice and easy to debug!
Thanks to this boilerplate and redux-toolkit, the state management is ready out of the box.
A complete example is even included. This way, you can easier understand how it works.
To deal with the navigation, React Navigation is THE reference for screen navigation.
For the internationalization we use I18next. Well-know library, really easy to use and
providing nice hooks.

redux-toolkit-wrapper

This project is a Redux-toolkit wrapper (yes... it's obvious ๐Ÿ˜…) used to write less code regarding classic CRUD operations.
Redux-toolkit provide a lot of abstraction for async operations, but we always have to create a loading and error
state and associated reducers.
Redux-toolkit-wrapper abstract these async operations. For a classic "fetch one user" operation all you need is adding these files :

javascript title="src/store/user/fetchone.js"
import {
  buildAsyncState, buildAsyncReducers, buildAsyncActions,
} from '@thecodingmachine/redux-toolkit-wrapper'
import fetchOneUserService from '@/Services/User/FetchOne'

export default {
  initialState: buildAsyncState('fetchOne'),
  action: buildAsyncActions('user/fetchOne', fetchOneUserService),
  reducers: buildAsyncReducers({
    errorKey: 'fetchOne.error',
    loadingKey: 'fetchOne.loading',
  }),
}
javascript title="src/store/user/index.js"
const sliceInitialState = {
  item: {},
}

export default buildSlice('user', [FetchOne], sliceInitialState).reducer

Next, you can use your state in your container like this:

javascript
import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { View, ActivityIndicator, Text } from 'react-native'
import FetchOne from '@/Store/User/FetchOne'

const ExampleContainer = () => {
  const dispatch = useDispatch()

  const user = useSelector(state => state.user.item)
  const fetchOneUserLoading = useSelector(state => state.user.fetchOne.loading)
  const fetchOneUserError = useSelector(state => state.user.fetchOne.error)

  useEffect(() => {
    dispatch(FetchOne.action(id))
  }, [dispatch])

  return (
    <View>
        {fetchOneUserLoading && <ActivityIndicator />}
        {fetchOneUserError ? (
          <Text style={Fonts.textRegular}>{fetchOneUserError.message}</Text>
        ) : (
          <Text style={Fonts.textRegular}>
            {t('example.helloUser', { name: user.name })}
          </Text>
        )}
    </View>
  )
}

export default ExampleContainer

That's this simple! ๐Ÿš€

What's in the box? ๐Ÿ“ฆ

Still hesitating ? Let's make a recap and see what this beautiful boilerplate can provide you:

  • No headaches! ๐Ÿค’ Thanks to the quick and easy install, the
    documentation and of course the included example! (if you have all the installed
    requirements
    of course)
  • Typescript ๐Ÿ’™ / Javascript ๐Ÿ’› ? Your project, your choice!
  • Never again sailing on troubled waters with React Navigation: THE powerful library to handle navigation ๐Ÿ“ฑ
  • Redux (with redux-toolkit and redux-toolkit-wrapper ๐Ÿ˜‰) : handling
    redux store has never been as easy as this!! โšก
  • DarkMode or colorful app? Give your users the power to choose!
    Multi-theming and darkMode support ๐ŸŒ—
  • French kisses aren't translatable, but you can translate your app! i18n friendly ๐ŸŒ
  • You don't like bug hunt? Use Flipper debugging ๐Ÿ›
  • Maintained by passionate developers โš›๏ธ

Just Test It ๐Ÿงช !!

Installation plugins โš™๏ธ

Freshly in the v3.0.0 we created an installation plugin system. Of course, the first plugin added is the typescript one. ๐Ÿ˜‰
We are now able to add local or npm plugins to our boilerplate in order to apply them during the installation.
This way, we get the app template with the features we asked for.
In other words, no unwelcome pieces of code will lay in your app architecture anymore.

You got it, it's only the beginning thinking about the many plugins we could create for this project. ๐Ÿคฉ
So wait and see what could be the next plugins...๐Ÿ•“๐Ÿค

Why this boilerplate? ๐Ÿ™

Before starting this project, we looked for already existing boilerplates.
We've found some, but while many were (and are always) awesome, we did not find what we were
looking for: a light, scalable, and flexible boilerplate with a great separation of concerns.

One of the most popular was
Matt Mcnamee's React Native Starter Kit,
which unfortunately missed Redux middleware and React Navigation.

Digging deeper in the react-native boilerplates (ignoring unmaintained projects),
many popular boilerplates were too opinionated: they
included 3rd party services or very strong architecture choices
that we were not comfortable with.
To name a few:

Finally, some did not contain the architecture we were looking for (the separation of concerns),
for example re-start.

One interesting exception was
Ignite IR Boilerplate "Andross", but after
consideration we decided not to use it because of the large amount of
unnecessary code/components it provided out of the box.

In 2021, some react-native boilerplates have changed. Let's see what are
the differences:

Boilerplate Difference from our
mcnamee/react-native-starter-kit No React Navigation (react-native-router-flux instead),
text
No Typescript support,
            Don't use the react-native-cli to init |

| bartonhammond/snowflake | Seems not maintained anymore (last release was in 2017) ๐Ÿ’ค |
| sysgears/apollo-universal-starter-kit | Is based on GraphQL using Apollo,
Don't use the react-native-cli to init |
| spencercarli/react-native-meteor-boilerplate | Seems not maintained (no release, last commit was in 2018) ๐Ÿ’ค |
| react-everywhere/re-start | Seems not maintained (last release was in 2017) ๐Ÿ’ค |
| infinitered/ignite | Specific folders for ignite-cli and boilerplate items,
MobX instead of Redux,
Expo ready,
Reactotron (ignite product) ready,
Typescript only |

So there is no reason to hesitate : come ๐Ÿงฒ, test ๐Ÿงช and leave a star โญ

Thanks for reading, See you for the next release. ๐Ÿท๏ธ


File: documentation/blog/2023-11-30-React-Native-Boilerplate-4.0.0.md


title: React Native Boilerplate 4.0.0 authors: jed hide_table_of_contents: false tags: [v4, boilerplate react, react-native, kickstart]

After using the boilerplate on several projects,
we decided to revisit some important aspects while still adhering to the core principles of the boilerplate:
separation of concerns, ease of setup, and maintainability.
We made several enhancements, which we'll detail here.

Improved Theming

Theming is a crucial aspect of any application.
Previously, we had designed a layered theming system where all variables could be customized for each theme,
including base colors and spacing.
Upon reflection, we found that this system, while effective, wasn't the most straightforward to use,
especially with the layered naming convention.

Additionally, being able to modify spacing between themes didn't make sense.
Furthermore, the variable names we used weren't always intuitive.
For instance, terms like 'medium' or 'large' didn't allow for easy interpolation between them.
It was even harder to find an intermediate value between 'medium' and 'regular,' for example.

As a result, we decided to simplify and improve the theming process, making it more efficient and comprehensive.

Configuration

Everything now revolves around a configuration file named _config.ts.
This file serves as a central configuration point where you can define the base theme values and declare theme variants.
We've moved away from the complex layering system in favor of a more reflective system with main themes and variants.

Theme Provider

To boost performance, we introduced a ThemeProvider component. This component provides the theme to the application,
preventing the need to regenerate the theme with every useTheme call.

Type Inference

We've also improved the type inference of the theme. Now each generated style is typed according to the theme configuration even if there are variants.
For example, let's imagine a configuration like this:

ts title=/src/theme/_config.ts
export const config = {
    //...
    fonts: {
        //...
        colors: {
            primary: 'blue',
        },
    },
    //...
    variants: {
        dark: {
            fonts: {
                colors: {
                    primary: 'darkblue',
                },
            },
        },
        premium: {
            fonts: {
                colors: {
                    primary: 'gold',
                },
            },
        }
    }
}

The generated type will be inferred at the perfect level:

Goodbye Redux ๐Ÿคง

Redux is a fantastic library, but it's not always the best solution for every project.
When we started the boilerplate, our goal was to provide a comprehensive solution for state management. In our initial version, we integrated Redux, Redux Persist, and Redux Saga, to name a few. These libraries were essential for managing the application's state, handling asynchronous requests, and persisting data.

However, over time, alternative solutions emerged,
particularly in the realm of data fetching.
It was with Redux Toolkit Query that we began version 3.
Nonetheless, we decided to part ways with it for version 4.

Our aim has always been to offer a lightweight yet comprehensive solution
without being too opinionated. Thus, we chose to remove Redux from the boilerplate
in favor of lighter and more straightforward alternatives.
It's important to note that global state management remains crucial in an application,
and several options are available:

  • Redux
  • Mobx
  • Zustand
  • Jotai
  • React Context
  • And more...

Now, in this version, for data fetching, we now use React Query,
an excellent library that's straightforward to use.
As for data storage, we rely on React Native MMKV, a native library known for its high performance and secure,
synchronous data storage capabilities.

Enhanced Documentation ๐Ÿ’™

We also took the opportunity to enhance the documentation.
It's now clearer and more comprehensive.
We've made an effort to make the documentation more accessible and easier to understand.
At times, we've added 'playgrounds' in the section related to theme generation,
allowing you to directly test the values you want and see the results for yourself


File: documentation/docs/04-Guides/04-Theming/03-Generated styles/01-Gutters.mdx


slug: /theming/generated-styles/gutters sidebar_label: Gutters title: Gutters id: theming-generated-styles_gutters keywords: [padding, margin, paddings, margins, gutters, spacings, gap]

import Gutters from "../../../../src/components/Gutters";

How to use ?

Generated styles provided by the gutters section of the theme configuration assist in applying margin and padding to your components.
You can access these styles using the following code:

javascript
const { gutters } = useTheme()

For more details, refer to the gutters section of the theme configuration.

Generated gutters

Here's the representation of the generated styles for a given GuttersConfig like the one below:

typescript
export const config = {
    // ...
    gutters: [...value],
    // ...
}

Where value is an array of numbers, the generated keys available through the gutters key will be the concatenation of the gutter name and the value, including:

  • margin_${value},
  • marginBottom_${value},
  • marginTop_${value},
  • marginRight_${value},
  • marginLeft_${value},
  • marginVertical_${value},
  • marginHorizontal_${value},
  • padding_${value},
  • paddingBottom_${value},
  • paddingTop_${value},
  • paddingRight_${value},
  • paddingLeft_${value},
  • paddingVertical_${value},
  • paddingHorizontal_${value},
  • gap_${value},

The corresponding values behind these keys will be:

javascript
{
    [gutter_name]: value
}

This structure simplifies the process of accessing and applying margin and padding styles with various gutter values.

Static gutter styles

Some gutter styles, don't require dynamic generation.
To accommodate this, we offer the staticGuttersStyles object that houses static styles for gutters.
You can use this file as-is or customize it to your preferences.
These styles will be seamlessly merged with the generated ones,
making them accessible through the gutters object of the useTheme hook.

Playground

Here's a simple playground that provides a visual representation of the objects generated from a given gutters configuration:


File: documentation/docs/04-Guides/04-Theming/03-Generated styles/02-Fonts.mdx


slug: /theming/generated-styles/fonts
sidebar_label: Fonts
title: Fonts
id: theming-generated-styles_fonts
keywords: [fonts, fontsize, fontcolor, textcolor, textsize, text]


import Fonts from "../../../../src/components/Fonts";

How to use ?

Generated styles provided by the fonts section of the theme configuration assist in applying font sizes and text colors to your components.
You can access these styles using the following code:

javascript
const { fonts } = useTheme()

For more details, refer to the fonts section of the theme configuration.

Generated fonts

Here is the representation of the generated styles for a given
FontsConfig like the one below:

ts title=/src/theme/theme.config.ts
export const config = {
    //...
    fonts: {
        sizes: sizesValues,
        colors: colorsValues,
    },
    //...
}

Where sizesValues is an array of numbers, sizeValue is an item of sizeValues, and colorsValues is an object with
colorsKey keys and colorsValue values, the generated styles are as follows:

font name Generated style
fonts.size__sizesValue_ { fontSize: sizeValue }
fonts.colorsKey { color: colorsValue }

Static fonts

Some fonts styles, such as the fontWeight property of a text style, don't require dynamic generation.
To accommodate this, we offer the staticFontStyles object that houses static styles for fonts.
You can use this file as-is or customize it to your preferences.
These styles will be seamlessly merged with the generated ones,
making them accessible through the fonts object of the useTheme hook.

Playground

Here's a simple playground that provides a visual representation of the objects generated from a given fonts configuration:


File: documentation/docs/04-Guides/04-Theming/03-Generated styles/03-Backgrounds.mdx


slug: /theming/generated-styles/backgrounds sidebar_label: Backgrounds title: Backgrounds id: theming-generated-styles_backgrounds keywords: [background, backgrounds, colors, color]

import Backgrounds from "../../../../src/components/Backgrounds";

How to use ?

The styles generated by the backgrounds section of the theme configuration are designed to apply background colors to your components.
To access these styles, you can use the following code:

javascript
const { backgrounds } = useTheme()

Generated backgrounds

Here is the representation of the generated styles for a given
BackgroundConfig like the one below:

ts title=/src/theme/theme.config.ts
export const config = {
    //...
    backgrounds: {
        [colorName]: colorValue,
        //...
    },
    //...
}

The generated styles take the following form:

background name Generated style
backgrounds.colorName { backgroundColor: colorValue }

These styles enable you to easily apply background colors to your components as needed.

Static backgrounds styles

Some background styles, don't require dynamic generation.
To accommodate this, we offer the staticBackgroundStyles object that houses static styles for background.
You can use this file as-is or customize it to your preferences.
These styles will be seamlessly merged with the generated ones,
making them accessible through the backgrounds object of the useTheme hook.

Playground

Here's a simple playground that provides a visual representation of the objects generated from a given backgrounds configuration:


File: documentation/docs/04-Guides/04-Theming/03-Generated styles/04-Borders.mdx


slug: /theming/generated-styles/borders sidebar_label: Borders title: Borders id: theming-generated-styles_borders keywords: [border, borders, radius, width, color, colors]

import Borders from "../../../../src/components/Borders";

How to use ?

Generated styles provided by the borders section of the theme configuration assist in applying border radius, width and color to your components.
You can access these styles using the following code:

javascript
const { borders } = useTheme()

For more details, refer to the borders section of the theme configuration.

Generated borders

Here is the representation of the generated styles for a given
BordersConfig like the one below:

ts title=/src/theme/theme.config.ts
export const config = {
    //...
    borders: {
        widths: widthsValues,
        radius: radiusValues,
        colors: colorsValues,
    },
    //...
}

Where widthsValues and radiusValues are arrays of numbers, widthValue is an item of widthsValues, radiusValue is an item of radiusValues, and colorsValues is an object with
colorsKey keys and colorsValue values, the generated styles are as follows:

border name Generated style
borders.w__widthValue_ { borderWidth: widthValue }
borders.wTop__widthValue_ { borderWidth: widthValue }
borders.wBottom__widthValue_ { borderWidth: widthValue }
borders.wLeft__widthValue_ { borderWidth: widthValue }
borders.wRight__widthValue_ { borderWidth: widthValue }
borders.rounded__radiusValue_ { borderRadius: radiusValue }
borders.roundedTop__radiusValue_ { borderRadius: radiusValue }
borders.roundedBottom__radiusValue_ { borderRadius: radiusValue }
borders.colorsKey { borderColor: colorsValue }

Static borders styles

Some border styles, don't require dynamic generation.
To accommodate this, we offer the staticBorderStyles object that houses static styles for border.
You can use this file as-is or customize it to your preferences.
These styles will be seamlessly merged with the generated ones,
making them accessible through the borders object of the useTheme hook.

Playground

Here's a simple playground that provides a visual representation of the objects generated from a given borders configuration:


File: documentation/docs/04-Guides/04-Theming/03-Generated styles/05-Layout.mdx


slug: /theming/generated-styles/layout sidebar_label: Layout title: Layout id: theming-generated-styles_layout keywords: [layout, flex, row, col, column, center, align, justify]

import Layout from '../../../../../template/src/theme/layout'

How to use ?

Static styles provided by the static/layout.ts file assist in applying layout styles to your components.
You can access these styles using the following code:

javascript
const { layout } = useTheme()

Default generated layout

Key Value
{key} {JSON.stringify(value)}

:::info
These styles are generated using the static/layout.ts file. You can modify the file to change the default styles.
:::


File: documentation/docs/04-Guides/04-Theming/01-Using.md


slug: /theming/how-to-use sidebar_label: How to use it? title: How to use it? id: theming-how-to-use keywords: [theme, theming, useTheme, hooks, themeProvider]

The boilerplate provides a pre-configured theme ready for use.
To make use of it, simply follow this section's instructions.
If you'd like to gain a deeper understanding of the theme configuration, please refer to
the configuration section for more details.

`useTheme` hook

If you need to access the style classes, you can use the useTheme hook in the following manner:

tsx
import { useTheme } from '@/theme';

const Example = () => {
    const {
      //highlight-start
      colors,
      variant,
      layout,
      gutters,
      fonts,
      backgrounds,
      borders,
      navigationTheme,
      components,
      //highlight-end
    } = useTheme();
    
    return (
        <View
            style={[
                //highlight-start
                layout.itemsCenter,
                layout.justifyCenter,
                //highlight-end
            ]}
        >
            
            {isError && (
                <Text style={[
                    //highlight-start
                    gutters.marginTop_30, 
                    fonts.font_16, 
                    fonts.text_red_500
                    //highlight-end
                ]}>
                    An error occured
                </Text>
            )}
        </View>
    )
}

Change theme

As mentioned in the configuration section, you have the flexibility to add new themes
(variants) and switch between them directly within the app. For example, if you have a default theme configured with a
dark variant, you can switch the current theme to dark at any point.

To achieve this, you can employ the useTheme hook as follows:

tsx
import { useTheme } from '@/theme';

const Example = () => {
    const { changeTheme } = useTheme();
    
    return (
         changeTheme('dark')}
        />
    )
}

:::tip
If you require assistance in defining a new theme variant, kindly consult the configuration section for guidance.
:::

Theme Provider

The magic of useTheme is made possible by our ThemeProvider component.
This main component handles the generation of all the styles in your application.
As we've emphasized, a clean separation of concerns is paramount to us.

That's why we've designed a single, transparent component, using the adapted context pattern
that takes care of generating all your styles, storing the theme variant,
and even offers you the flexibility to switch the theme for your entire app.
No black box magic here โ€“ you have full visibility into the code and the
freedom to enhance it as needed to meet your unique requirements.


File: documentation/docs/04-Guides/04-Theming/02-Configuration.md


slug: /theming/configuration sidebar_label: Configuration title: Configuration id: theme-configuration keywords: [theme, theming, configuration, config, colors, fonts, gutters, spacings, borders, navigation, variants]

Structure

The idea behind the theme configuration is to have a single source of truth for all the theme related values.
This is why the theme configuration is a simple object with the following structure:

Key Type Description
colors colorConfig Define global colors
fonts FontConfig Define colors and sizes to generate associated styles (color and fontSize)
gutters GuttersConfig Define sizes to generate associated styles (padding and margin)
backgrounds Record<string, string> Define colors generate associated styles (backgroundColor)
borders BordersConfig Define colors, sizes and radius to generate associated styles (borderColor, borderRadius, borderWidth)
navigationColors NavigationColorsConfig Define colors override ReactNavigation theme colors
variants VariantsConfig Define a new theme based on the previous values

Variants

A variant is a new theme based on the previous values.
It means that the default theme is based on the previous keys (fonts, gutters, backgrounds, borders, navigationColors)
to be generated and variant are just a way to create a new theme based on the previous values.

For example, if you want to create a dark theme, you can create a new variant based on the default theme and override the colors you want to change.

ts title=/src/theme/theme.config.ts
export const config = {
  //...
  // highlight-start
  backgrounds: {
    gray_200: '#DFDFDF',
  }, 
  // highlight-end
  //...
  variants: {
    dark: {
      // highlight-start
      backgrounds: {
        gray_200: '#000000',
      },
      // highlight-end
    },
  },
};

So here the theme dark will have the same values as the default theme except for the backgrounds.gray_200 value.

Statically generated styles

Some styles, including Backgrounds, Borders, Fonts and Gutters need to be dynamically generated depending on the actual theme.
But, in some cases, the configuration is not sufficient to generate all the styles you need. So, in this case, you will need to add some static styles.
In each style files you will find a static function to include non-config-based styles:

  • staticBackgroundStyles to generate static background styles
  • staticBorderStyles to generate static border styles
  • staticFontStyles to generate static font styles
  • staticGutterStyles to generate static gutter styles

into these files, you will be able to add any style you want.
All of these will be available

Components styling

Sometimes, you will want to create some style object for a specific component.
As we want to keep the theme configuration as the single source of truth, we don't want to have some style object in the component itself.
Plus, we want to be able to use the theme configuration variables to generate these styles for example if we want to style a button based on the theme colors.

This is why we introduce the components file in the theme directory.
The benefit of this is that you will be able to create a style object for a specific component and use the theme styles to generate these styles.

For example, if you want to style a circle Button component, you will create a circleButton entry in the components file.

ts title=/src/theme/components.ts
export default ({ layout, backgrounds, fonts }: ComponentTheme) => {
  return {
    buttonCircle: {
      ...layout.justifyCenter,
      ...layout.itemsCenter,
      ...backgrounds.purple100,
      ...fonts.gray400,
      height: 70,
      width: 70,
      borderRadius: 35,
    },
  } as const satisfies Record<string, ImageStyle | TextStyle | ViewStyle>;
};