Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions .vscode/project.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@
"body": [
"<View className=\"flex-1 items-center justify-center\">",
" $1",
"</View>"
"</View>",
],
"description": "A Simple View "
"description": "A Simple View ",
},
"Text": {
"prefix": "t",
"body": [
"<Text variant=\"body\" className=\"text-center\">",
" $1",
"</Text>"
"</Text>",
],
"description": "A Simple Text"
"description": "A Simple Text",
},
"export *": {
"prefix": "ex *",
"body": ["export * from '.$1';"],
"description": "export *"
"description": "export *",
},
"Component": {
"prefix": "comp",
"body": [
"import * as React from 'react';",
"",
"import { Text, View } from '@/ui';",
"import { Text, View } from '@/components/ui';",
"",
"type Props = {",
" $2",
Expand All @@ -39,9 +39,9 @@
" </View>",
" );",
"};",
""
"",
],
"description": "Component"
"description": "Component",
},
// https://snippet-generator.app/?description=useQuery+with+variables&tabtrigger=useqv&snippet=import+type+%7B+AxiosError+%7D+from+%27axios%27%3B%0Aimport+%7B+createQuery+%7D+from+%27react-query-kit%27%3B%0A%0Aimport+%7B+client+%7D+from+%27..%2Fcommon%27%3B%0A%0Atype+Variables+%3D+%7B%243%7D%3B%0Atype+Response+%3D+%7B%244%7D%3B%0A%0Aexport+const+use%241+%3D+createQuery%3CResponse%2C+Variables%2C+AxiosError%3E%28%7B%0A++queryKey%3A+%5B%27%242%27%5D%2C+%0A++fetcher%3A+%28variables%29+%3D%3E+%7B%0A++++return+client%0A++++++.get%28%60%242%2F%5C%5C%24%7Bvariables.%24%7B5%7D%7D%60%29%22%2C%0A++++++.then%28%28response%29+%3D%3E+response.data%29%3B%0A++%7D%2C%0A%7D%29%3B%0A&mode=vscode
"useQuery with variables": {
Expand All @@ -63,9 +63,9 @@
" .then((response) => response.data);",
" },",
"});",
""
"",
],
"description": "useQuery with variables"
"description": "useQuery with variables",
},
//https://snippet-generator.app/?description=useQuery&tabtrigger=useq&snippet=import+type+%7B+AxiosError+%7D+from+%27axios%27%3B%0Aimport+%7B+createQuery+%7D+from+%27react-query-kit%27%3B%0A%0Aimport+%7B+client+%7D+from+%27..%2Fcommon%27%3B%0A%0Atype+Response+%3D+%7B%243%7D%3B%0Atype+Variables+%3D+void%3B%0A%0Aexport+const+use%241+%3D+createQuery%3CResponse%2C+Variables%2C+AxiosError%3E%28%7B%0A++queryKey%3A+%5B%27%242%27%5D%2C%0A++fetcher%3A+%28%29+%3D%3E+%7B%0A++++return+client.get%28%60%242%60%29.then%28%28response%29+%3D%3E+response.data.posts%29%3B%0A++%7D%2C%0A%7D%29%3B%0A&mode=vscode
"useQuery": {
Expand All @@ -85,9 +85,9 @@
" return client.get(`$2`).then((response) => response.data.posts);",
" },",
"});",
""
"",
],
"description": "useQuery"
"description": "useQuery",
},
//https://snippet-generator.app/?description=useInfiniteQuery&tabtrigger=useiq&snippet=import+type+%7B+AxiosError+%7D+from+%27axios%27%3B%0Aimport+%7B+createInfiniteQuery+%7D+from+%27react-query-kit%27%3B%0A%0Aimport+%7B+client+%7D+from+%27..%2Fcommon%2Fclient%27%3B%0Aimport+%7B+DEFAULT_LIMIT%2C+getNextPageParam+%7D+from+%27..%2Fcommon%2Futils%27%3B%0Aimport+type+%7B+PaginateQuery+%7D+from+%27..%2Ftypes%27%3B%0A%0Atype+Response+%3D+void%3B%0Atype+Variables+%3D+PaginateQuery%3C%243%3E%3B%0A%0Aexport+const+use%241+%3D+createInfiniteQuery%3CResponse%2C+Variables%2C+AxiosError%3E%28%7B%0A++queryKey%3A+%5B%27%242%27%5D%2C%0A++fetcher%3A+%28_variables%3A+any%2C+%7B+pageParam+%7D%29%3A+Promise%3CResponse%3E+%3D%3E+%7B%0A++++return+client%28%7B%0A++++++url%3A+%60%2F%242%2F%60%2C%0A++++++method%3A+%27GET%27%2C%0A++++++params%3A+%7B%0A++++++++limit%3A+DEFAULT_LIMIT%2C%0A++++++++offset%3A+pageParam%2C%0A++++++%7D%2C%0A++++%7D%29.then%28%28response%29+%3D%3E+response.data%29%3B%0A++%7D%2C%0A++getNextPageParam%2C%0A++initialPageParam%3A+0%2C%0A%7D%29%3B&mode=vscode
"useInfiniteQuery": {
Expand Down Expand Up @@ -117,9 +117,9 @@
" },",
" getNextPageParam,",
" initialPageParam: 0,",
"});"
"});",
],
"description": "useInfiniteQuery"
"description": "useInfiniteQuery",
},

//https://snippet-generator.app/?description=useMutation+&tabtrigger=usem&snippet=import+type+%7B+AxiosError+%7D+from+%27axios%27%3B%0Aimport+%7B+createMutation+%7D+from+%27react-query-kit%27%3B%0A%0Aimport+%7B+client+%7D+from+%27..%2Fcommon%27%3B%0A%0Atype+Variables+%3D+%7B%243%7D%3B%0Atype+Response+%3D+%7B%244%7D%3B%0A%0Aexport+const+use%241+%3D+createMutation%3CResponse%2C+Variables%2C+AxiosError%3E%28%0A++async+%28variables%29+%3D%3E%0A++++client%28%7B%0A++++++url%3A+%27%242%27%2C%0A++++++method%3A+%27POST%27%2C%0A++++++data%3A+variables%2C%0A++++%7D%29.then%28%28response%29+%3D%3E+response.data%29%0A%29%3B&mode=vscode
Expand All @@ -141,13 +141,13 @@
" method: 'POST',",
" data: variables,",
" }).then((response) => response.data)",
"});"
"});",
],
"description": "useMutation "
"description": "useMutation ",
},
"navigate": {
"prefix": "navigate",
"body": ["const { navigate } = useNavigation();", ""],
"description": "navigate"
}
"description": "navigate",
},
}
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = function (api) {
root: ['./'],
alias: {
'@': './src',
'@env': './src/core/env.js',
'@env': './src/lib/env.js',
},
extensions: [
'.ios.ts',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Code from '../../../components/code.astro';

Managing environment variables in your project is an essential task, but it can also be challenging. That's why we have included a complete setup for environment variables in this project. This setup comes with validation and type-checking using the `zod` library.

All the code related to environment variables is located in the `env.js` and `src/core/env.js` files. The `env.js` read the `APP_ENV` variable and loads the correct `.env` file, then defines the `zod` schema for the environment variables for client and build-time, parses the `_env` object, and returns the parsed object, or throws errors in case of invalid or missing variables.
All the code related to environment variables is located in the `env.js` and `src/lib/env.js` files. The `env.js` read the `APP_ENV` variable and loads the correct `.env` file, then defines the `zod` schema for the environment variables for client and build-time, parses the `_env` object, and returns the parsed object, or throws errors in case of invalid or missing variables.

To increase security, we are splitting environment variables into two parts:

Expand Down Expand Up @@ -90,7 +90,7 @@ export const client = axios.create({
```

:::note[Important]
Using `import { Env } from '@env';` will import the env from the `src/core/env.js` file, which export client only env vars.
Using `import { Env } from '@env';` will import the env from the `src/lib/env.js` file, which export client only env vars.
:::

6. Use `APP_ENV` to load the correct `.env` file :
Expand Down Expand Up @@ -147,7 +147,7 @@ Now it's as easy as importing `Env` , `ClientEnv` and `withEnvSuffix` from the `

Here, we added a separate file to export all variables that have already been passed in the `extra` property to the client side. We added a little bit of magic to make it type-safe and easy to use.

<Code file="src/core/env.js" />
<Code file="src/lib/env.js" />

Now the environment variables are ready to use in your project. You can access them in your code by importing `Env` from `@env` and using it like this:

Expand Down
38 changes: 19 additions & 19 deletions docs/src/content/docs/getting-started/project-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ If you open the new project in VSCode you will see the following structure:
- login.tsx
- onboarding.tsx
- components ## any reusable components
- ui ## core ui and theme configuration
- button.tsx
- checkbox.tsx
- colors.js
- focus-aware-status-bar.tsx
- icons
- image.tsx
- index.tsx
- input.tsx
- list.tsx
- modal.tsx
- progress-bar.tsx
- select.tsx
- text.tsx
- utils.tsx
- buttons.tsx
- card.tsx
- colors.tsx
Expand All @@ -35,7 +50,7 @@ If you open the new project in VSCode you will see the following structure:
- settings/
- title.tsx
- typography.tsx
- core ## core files such as auth, localization, storage and more
- lib ## core files such as auth, localization, storage and more
- auth
- env.js
- hooks
Expand All @@ -51,29 +66,14 @@ If you open the new project in VSCode you will see the following structure:
- en.json
- types ## global types
- index.ts
- ui ## core ui and theme configuration
- button.tsx
- checkbox.tsx
- colors.js
- focus-aware-status-bar.tsx
- icons
- image.tsx
- index.tsx
- input.tsx
- list.tsx
- modal.tsx
- progress-bar.tsx
- select.tsx
- text.tsx
- utils.tsx

</FileTree>

- `ui`: This folder contains all the UI components and the theme configuration. We provide minimal components with a basic `obytes` theme. You can add your own components and theme configuration here.
- `components/ui`: This folder contains all the UI components and the theme configuration. We provide minimal components with a basic `obytes` theme. You can add your own components and theme configuration here.

- `components`: This folder contains the components of the app. mainly components used inside the app folder. The only difference between `ui` and `components` is that `ui` is more generic and can be used in any project, while `components` are more specific to the project.
- `components`: This folder contains the components of the app. mainly components used inside the app folder.

- `core`: This folder contains the core files, such as authentication, localization, storage, and more. It can be shared with other projects. That's why we are only including modules that have nothing to do with project logic. This approach helps us share code between projects and also update the starter with new features.
- `lib`: This folder contains the core files, such as authentication, localization, storage, and more. It can be shared with other projects. That's why we are only including modules that have nothing to do with project logic. This approach helps us share code between projects and also update the starter with new features.

- `app`: This folder contains the routes of the app, along with its layout routes such as stack and tab navigation structures. We provide a basic navigation structure for the demo app that you can modify to fit your needs.

Expand Down
8 changes: 4 additions & 4 deletions docs/src/content/docs/guides/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Zustand works very well with TypeScript and can be easily used outside the React

As mentioned earlier, we use Zustand to manage the authentication state of the application. The authentication store is located in `src/store/auth` and is utilized for managing the authentication state of the application.

<CodeBlock file="src/core/auth/index.tsx" />
<CodeBlock file="src/lib/auth/index.tsx" />

The store is composed of 2 states and 3 actions:

Expand All @@ -32,7 +32,7 @@ The store is composed of 2 states and 3 actions:

- `useToken`: The token of the user. It is used to authenticate the user to the API. It is stored in the storage of the device and we use it to hydrate the authentication status state when the application is started.

For the Demo app `useToken` is a simple object that contains the `accessToken` and the `refreshToken`. You can add more fields if you update the `TokenType` type in `src/core/auth/utils.ts`.
For the Demo app `useToken` is a simple object that contains the `accessToken` and the `refreshToken`. You can add more fields if you update the `TokenType` type in `src/lib/auth/utils.ts`.

- `signIn`: TThe function performs user sign-in. It accepts a token as a parameter, sets the token state, stores it locally, and updates the status to `signIn`.

Expand All @@ -42,10 +42,10 @@ The store is composed of 2 states and 3 actions:

## Use Authentication store

You guessed it, you only need to import the store from `@/core` and use it in your component or even call store actions from outside React.
You guessed it, you only need to import the store from `@/lib` and use it in your component or even call store actions from outside React.

```tsx
import { useAuth, hydrate } from '@/core';
import { useAuth, hydrate } from '@/lib';

hydrate(); // call this when the application is started to check if the user is authenticated or not

Expand Down
12 changes: 6 additions & 6 deletions docs/src/content/docs/guides/internationalization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ The starter comes with a basic internationalization setup. It uses [expo-localiz

## Adding a new language

Mainly the demo app supports two languages: English and Arabic (RTL). You can add more languages by adding the translation files in the `src/translations` folder and adding the language code to the `src/core/i18n/resources.ts` file.
Mainly the demo app supports two languages: English and Arabic (RTL). You can add more languages by adding the translation files in the `src/translations` folder and adding the language code to the `src/lib/i18n/resources.ts` file.

<CodeBlock file="src/core/i18n/resources.ts" />
<CodeBlock file="src/lib/i18n/resources.ts" />

:::tip
Anything related to internationalization should be found in the `src/core/i18n` folder.
Anything related to internationalization should be found in the `src/lib/i18n` folder.
:::

## Using translations in your app
Expand All @@ -30,7 +30,7 @@ The i18n core module provides a set of utility functions to help you use transla
import React from 'react';
import { useTranslation } from 'react-i18next';

import { Text } from '@/ui';
import { Text } from '@/components/ui';

export const Foo = () => {
const { t } = useTranslation();
Expand All @@ -47,7 +47,7 @@ or as `Text` component comes with translation support, you can easily use it as
```tsx
import React from 'react';

import { Text } from '@/ui';
import { Text } from '@/components/ui';

export const Foo = () => {
return <Text className="text-center" tx="settings.language" />;
Expand All @@ -58,7 +58,7 @@ export const Foo = () => {

Additionally, the `useSetLanguage` hook will save the selected language in device storage using `MMKV` and will be used as the default language when the app is opened again As well as adding some extra config for RTL languages while updating the selected language.

<CodeBlock file="src/core/i18n/utils.tsx" />
<CodeBlock file="src/lib/i18n/utils.tsx" />

## Robust translation

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/guides/storage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ import CodeBlock from '../../../components/code.astro';

The starter comes with a simple storage module that uses [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) to store data in a key-value format. We also added a simple storage utility to assist you in using the storage module.

<CodeBlock file="src/core/storage.tsx" />
<CodeBlock file="src/lib/storage.tsx" />

The `react-native-mmkv` library provides various features such as using hooks and adding encryption to stored data. Feel free to check the [official docs](https://github.com/mrousavy/react-native-mmkv) for more information.
6 changes: 3 additions & 3 deletions docs/src/content/docs/recipes/sentry-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ The starter kit did not come with Sentry pre-configured, but it's very easy to s
```

8. Now you are ready to initialize Sentry in your app.
Create a new file `src/core/sentry.ts` and add the following code:
Create a new file `src/lib/sentry.ts` and add the following code:

```tsx title='src/core/sentry.ts'
```tsx title='src/lib/sentry.ts'
import { useNavigationContainerRef } from 'expo-router';
import { useEffect } from 'react';
import * as Sentry from '@sentry/react-native';
Expand Down Expand Up @@ -170,7 +170,7 @@ The starter kit did not come with Sentry pre-configured, but it's very easy to s
Then, initialize Sentry and configure it with navigation in your `src/app/_layout.tsx` file:

```tsx title='src/app/_layout.tsx'
import { initSentry, useSentryNavigationConfig } from '@/core/sentry';
import { initSentry, useSentryNavigationConfig } from '@/lib/sentry';
import * as Sentry from '@sentry/react-native';

initSentry();
Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/testing/unit-testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ First, let's create a new file called `login-form.test.tsx` in the `src/screens/

<CodeBlock file="./src/components/login-form.test.tsx" />

As you may notice from the code, we are importing a bunch of things from the `@/core/test-utils` directory. This is a simple file that exports everything from the `@testing-library/react-native` library and overrides the `render` function to wrap the component with the providers we need. This way, we don't have to import the providers in every test file.
As you may notice from the code, we are importing a bunch of things from the `@/lib/test-utils` directory. This is a simple file that exports everything from the `@testing-library/react-native` library and overrides the `render` function to wrap the component with the providers we need. This way, we don't have to import the providers in every test file.

:::tip
You can update this file to add any other providers you need to wrap your components with as well as any other utility functions you need to use in your tests.

<CodeBlock file="src/core/test-utils.tsx" />
<CodeBlock file="src/lib/test-utils.tsx" />

use `setup` function in case you need to test interactions with the component. It returns a user (userEvent) object that you can use to interact with the component.
:::
Expand Down
8 changes: 4 additions & 4 deletions docs/src/content/docs/ui-and-theme/Forms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ As we mention in the components section of the documentation [here](../component

Here is the complete code of our `ControlledInput` when we use `useController` hook from react-hook-form to handle form state and validation rules:

<CodeBlock file="src/ui/input.tsx" />
<CodeBlock file="src/components/ui/input.tsx" />

If you want to create your own controlled component, you just need to make sure your component props type extends from `InputControllerType` the same way we are using it with `ControlledInput`.
Here is another example of a Select input we create using the same approach as `ControlledInput`:

<CodeBlock file="src/ui/select.tsx" />
<CodeBlock file="src/components/ui/select.tsx" />

## Use Case

Expand Down Expand Up @@ -57,8 +57,8 @@ import React from 'react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';

import { useAuth } from '@/core';
import { Button, ControlledInput, View } from '@/ui';
import { useAuth } from '@/lib';
import { Button, ControlledInput, View } from '@/components/ui';

const schema = z.object({
email: z.string().email(),
Expand Down
Loading
Loading