Browse Source

Add NativeWind styling guide and RN docs

Add a new Styling with NativeWind guide for the React Native template and update related docs and assets. This commit introduces docs/en/framework/ui/react-native/styling-with-nativewind.md (theme tokens, dark mode, useThemeColors, customization), adds images (rn-home-screen.png, rn-nav-comparison.png) and replaces rn-login-iphone.png. It also updates the React Native index page to mention NativeWind, adds a navigation overview, and registers the new guide in docs-nav.json. Finally, the mobile-applications.md files for the layered-web-application and microservice templates were updated to reference NativeWind and to clarify the project structure and NativeWind config files.
pull/25350/head
Fahri Gedik 5 months ago
parent
commit
b33d666541
  1. 4
      docs/en/docs-nav.json
  2. 72
      docs/en/framework/ui/react-native/index.md
  3. 159
      docs/en/framework/ui/react-native/styling-with-nativewind.md
  4. BIN
      docs/en/images/rn-home-screen.png
  5. BIN
      docs/en/images/rn-login-iphone.png
  6. BIN
      docs/en/images/rn-nav-comparison.png
  7. 12
      docs/en/solution-templates/layered-web-application/mobile-applications.md
  8. 12
      docs/en/solution-templates/microservice/mobile-applications.md

4
docs/en/docs-nav.json

@ -1873,6 +1873,10 @@
"text": "Overview", "text": "Overview",
"path": "framework/ui/react-native", "path": "framework/ui/react-native",
"isIndex": true "isIndex": true
},
{
"text": "Styling with NativeWind",
"path": "framework/ui/react-native/styling-with-nativewind.md"
} }
] ]
}, },

72
docs/en/framework/ui/react-native/index.md

@ -18,6 +18,8 @@
The ABP platform provides a basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated with your ABP-based backends**. The ABP platform provides a basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated with your ABP-based backends**.
> The startup template UI is built with **[NativeWind v4](https://www.nativewind.dev/)** (Tailwind CSS for React Native) on top of a shadcn-inspired neutral palette, with full **light/dark mode** support. See [Styling with NativeWind](styling-with-nativewind.md) for the styling system reference.
![React Native gif](../../../images/react-native-introduction.gif) ![React Native gif](../../../images/react-native-introduction.gif)
## How to Prepare Development Environment ## How to Prepare Development Environment
@ -137,19 +139,85 @@ In the image above, you can start the application on an Android emulator, an iOS
### Expo ### Expo
![React Native login screen on iPhone 16](../../../images/rn-login-iphone.png) Press **i** to open the iOS simulator, or scan the QR code from the Expo CLI with your phone to run on a physical device.
### Android Studio ### Android Studio
1. Start the emulator in **Android Studio** before running the `yarn start` or `npm start` command. 1. Start the emulator in **Android Studio** before running the `yarn start` or `npm start` command.
2. Press **a** to open in Android Studio. 2. Press **a** to open in Android Studio.
![React Native login screen on Android Device](../../../images/rn-login-android-studio.png) <img width="360" src="../../../images/rn-login-iphone.png" alt="React Native login screen" />
Enter **admin** as the username and **1q2w3E\*** as the password to log in to the application. Enter **admin** as the username and **1q2w3E\*** as the password to log in to the application.
The application is up and running. You can continue to develop your application based on this startup template. The application is up and running. You can continue to develop your application based on this startup template.
## Navigation
The startup template ships with **two navigation styles**, switchable when the project is created:
- **Bottom Tab** — *the default* — three tabs at the bottom of the screen: **Home**, **Settings** and **Account**.
- **Drawer** — a side menu (hamburger) with two items: **Home** and **Settings**.
<img width="600" src="../../../images/rn-nav-comparison.png" alt="Bottom Tab vs Drawer navigation comparison" />
Each top-level destination is its own native stack (`@react-navigation/native-stack`), so deeper navigation inside a tab/drawer item keeps that area's history isolated. Both modes share the same screens — only the entry surface and the auth flow placement change.
> **How to choose:** The mode is selected in **ABP Studio** during the *Mobile Framework* step (or via the `navigation_type` template config when using the CLI). To switch later, you can manually replace `BottomTabNavigator` with `DrawerNavigator` (or vice versa) in `src/AppContainer.tsx` and adjust `src/navigators/types.ts` accordingly.
### Bottom Tab Navigation (default)
The root navigator is `BottomTabNavigator` (`src/navigators/BottomTabNavigator.tsx`) with three stacks:
- **HomeTab** → `HomeNavigator` → `HomeScreen` (hero greeting + feature cards).
- **SettingsTab** → `SettingsNavigator` → `SettingsScreen` (language, theme, profile/password shortcuts).
- **AccountTab** → `AccountNavigator` — *conditional stack* based on the authentication state read from Redux:
- **Authenticated:** `AccountScreen` → `ChangePasswordScreen`, `ProfilePictureScreen`.
- **Guest:** `LoginScreen` → `RegisterScreen`, `ForgotPasswordScreen`, `ResetPasswordScreen`.
Tab bar colors (active/inactive tint, background, border) are sourced from the `useThemeColors` hook so the bar follows the active light/dark theme.
#### The Account Screen
`AccountScreen` (`src/screens/Account/AccountScreen.tsx`) is the home of the AccountTab when the user is signed in. Its layout follows an iOS-style grouped pattern:
1. **Profile header** — circular avatar (profile picture or first-letter fallback), full name and email, centered at the top.
2. **Account actions card** — a single rounded card containing two rows with leading icon chips:
- **Profile Picture** → navigates to `ProfilePictureScreen`.
- **Change Password** → navigates to `ChangePasswordScreen`.
3. **Destructive logout button** — an outlined `destructive`-colored button that calls the `useLogout` hook.
### Drawer Navigation (alternative)
When the drawer mode is selected, `DrawerNavigator` (`src/navigators/DrawerNavigator.tsx`) replaces the bottom tabs. It exposes two drawer items:
- **HomeStack** → `HomeNavigator` → `HomeScreen`, plus the auth flow (`LoginScreen`, `RegisterScreen`, `ForgotPasswordScreen`, `ResetPasswordScreen`).
- **SettingsStack** → `SettingsNavigator` → `SettingsScreen`, `ChangePasswordScreen`, `ProfilePictureScreen`.
Note that there is **no `AccountTab` / `AccountScreen` in drawer mode** — auth lives in the Home stack and profile/password actions live in the Settings stack. The drawer side panel itself is fully custom.
#### The Drawer Content
`DrawerContent` (`src/components/DrawerContent/DrawerContent.tsx`) is the custom side panel rendered by `DrawerNavigator` via the `drawerContent` prop. From top to bottom:
1. **User header** — circular avatar (image or first-letter fallback) + full name + email when authenticated.
2. **Divider**.
3. **Navigation items** — Home and Settings rows with leading Ionicons; tapping navigates and closes the drawer.
4. **Auth row** — when authenticated, a **Logout** row that calls `useLogout`; when guest, a **Login** row that navigates to the Login screen inside `HomeStack`.
The whole panel uses NativeWind classes with `dark:` variants, so it follows the active theme automatically.
### Adding a New Screen
To add a screen to either navigation mode:
1. Create the screen component under `src/screens/<FeatureName>/<FeatureName>Screen.tsx` and export it from `src/screens/index.ts`.
2. Register it as a `Stack.Screen` inside the appropriate navigator (e.g. `HomeNavigator`, `SettingsNavigator`, or `AccountNavigator`).
3. Add the route to the matching `*ParamList` in `src/navigators/types.ts` so the screen props stay typed.
If the new screen needs to appear at the *root* level (a new tab or drawer item rather than a child of an existing stack), edit `BottomTabNavigator.tsx` or `DrawerNavigator.tsx` and update the corresponding `BottomTabParamList` / `RootDrawerParamList` type.
## How to Configure & Run the Backend (Required for Emulator/Simulator Testing) ## How to Configure & Run the Backend (Required for Emulator/Simulator Testing)
> React Native application does not trust the auto-generated .NET HTTPS certificate. You should use **HTTP** during the development. > React Native application does not trust the auto-generated .NET HTTPS certificate. You should use **HTTP** during the development.

159
docs/en/framework/ui/react-native/styling-with-nativewind.md

@ -0,0 +1,159 @@
```json
//[doc-seo]
{
"Description": "Learn how the ABP React Native startup template is styled with NativeWind v4 (Tailwind CSS for React Native), including the semantic color tokens, dark mode and theme customization."
}
```
# Styling with NativeWind
The ABP React Native startup template uses **[NativeWind v4](https://www.nativewind.dev/)** — Tailwind CSS for React Native. Most components are styled through utility `className` props that are compiled at build time, so there is almost no styling runtime cost. The design system is based on the **shadcn/ui** neutral palette and supports **light and dark themes** out of the box.
> This page documents the styling system that ships with the template. For the general getting-started flow (installing tools, running the app, configuring the backend), see [Getting Started with React Native](index.md).
<img width="360" src="../../../images/rn-home-screen.png" alt="HomeScreen built with NativeWind" />
---
## 1. Project Files
NativeWind is wired in through a small set of configuration files at the root of the React Native project:
| File | Purpose |
|------|---------|
| `tailwind.config.js` | Defines the design tokens (colors, spacing, border radius), enables `darkMode: 'class'`, and registers the NativeWind preset. This is the source of truth for the theme. |
| `global.css` | Tailwind entry point with the three base directives (`@tailwind base; @tailwind components; @tailwind utilities;`). |
| `metro.config.js` | Wraps the default Expo Metro config with `withNativeWind(...)` and points it at `global.css`. |
| `babel.config.js` | Adds the `nativewind/babel` preset and sets `jsxImportSource: 'nativewind'` on `babel-preset-expo` so JSX understands the `className` prop. |
| `nativewind-env.d.ts` | TypeScript triple-slash reference (`/// <reference types="nativewind/types" />`) that adds `className` typings to React Native components. |
All of these files come pre-configured in the template. You normally only need to edit `tailwind.config.js` to customize the theme.
---
## 2. Semantic Color Tokens
Instead of raw color names like `bg-zinc-900`, the template exposes a small set of **semantic tokens** that follow the shadcn/ui convention. Each token has a default (light) value and a `dark` variant, and many also carry a paired `foreground` color for text/icons placed on top.
| Token | Use it for |
|-------|-----------|
| `background` / `foreground` | Screen background and primary text. |
| `card` / `card-border` | Surface containers (settings rows, feature cards) and their 1px border. |
| `primary` / `primary-foreground` | Filled call-to-action buttons. |
| `secondary` / `secondary-foreground` | Subtle filled elements such as icon chips inside cards. |
| `muted` / `muted-foreground` | Backgrounds and text for secondary information (subtitles, helper text). |
| `accent` / `accent-foreground` | Highlighted/active state — also used as the active tint of the bottom tab bar. |
| `destructive` / `destructive-foreground` | Delete/danger actions and error states. |
| `border` | Generic separators and outline borders. |
| `input` | Border color for text inputs (Paper `TextInput` outline). |
| `ring` | Focus ring/outline color. |
All token values live in `tailwind.config.js` under `theme.extend.colors`. Refer to that file for the exact hex values.
The template also extends Tailwind's spacing and border-radius scales so paddings and corners stay consistent across screens:
* **Spacing:** `xs` (4px), `sm` (8px), `md` (16px), `lg` (24px), `xl` (32px) — usable as `p-md`, `mt-lg`, `gap-sm`, etc.
* **Border radius:** `rounded-sm` (4px), `rounded-md` (8px), `rounded-lg` (12px), `rounded-xl` (16px), `rounded-2xl` (20px).
---
## 3. Dark Mode
Dark mode is enabled with `darkMode: 'class'` in `tailwind.config.js` and is driven by the device color scheme via NativeWind's `useColorScheme()` hook. Each color token has a sibling `*-dark` (and where applicable `*-dark-foreground`) variant, and components opt into it with the `dark:` prefix on their classes:
```tsx
<View className="flex-1 bg-background dark:bg-background-dark">
<Text className="text-foreground dark:text-foreground-dark">
Hello
</Text>
</View>
```
> **Pattern note.** The token shape used in this template is `{ DEFAULT, dark }` (and `{ foreground, 'dark-foreground' }` where applicable), so the dark-mode class is `dark:bg-background-dark` — not `dark:bg-background`. Follow this convention when you add new screens so the theme switch behaves consistently across the app.
The user can also switch themes manually from the **Settings** screen (system / light / dark), and the choice is persisted via Redux.
<img width="360" src="../../../images/rn-home-screen.png" alt="HomeScreen with light and dark theme" />
---
## 4. The `useThemeColors` Hook
A handful of APIs in the template do not accept a `className` — they need a *color value*. Examples:
* `react-native-paper`'s `TextInput` (which the template still uses for outlined inputs and validation styling).
* React Navigation's `screenOptions` (header background, tab bar tint, etc.).
* The native status bar.
For these cases the template ships a `useThemeColors` hook at `src/hooks/UseThemeColors.ts`. It returns theme-aware values that mirror the Tailwind tokens:
```ts
const {
primaryContainer, // Paper TextInput surface
headerBg, // Navigator headers
headerText,
iconColor, // Inactive icon tint
accentColor, // Active icon tint / focused tab
destructiveColor,
inputBorderColor,
} = useThemeColors();
```
**Rule of thumb:** prefer `className` with `dark:` variants whenever the component supports it; reach for `useThemeColors` only for the components listed above.
---
## 5. React Native Paper
`react-native-paper` is still in the template's `package.json`, but its usage has been narrowed down to a single component: **`TextInput`** in outlined mode (used for forms because of its strong validation/error UI). Buttons, lists, modals, drawers, and icons are all NativeWind + `@expo/vector-icons` (Ionicons) now.
If you add new forms, follow the same split:
* Use Paper's `TextInput` (with values from `useThemeColors`) for text fields.
* Use plain `View`/`Text`/`Pressable` with NativeWind classes for everything else.
---
## 6. Customizing the Theme
Most customization happens in `tailwind.config.js`. To introduce a brand color, extend the `colors` map and reuse the `{ DEFAULT, dark }` shape so the `dark:` variants keep working:
```js
// tailwind.config.js
module.exports = {
// ...
theme: {
extend: {
colors: {
// ...
brand: {
DEFAULT: '#2563eb',
dark: '#3b82f6',
foreground: '#ffffff',
'dark-foreground': '#ffffff',
},
},
},
},
};
```
You can then use it from any component:
```tsx
<Pressable className="bg-brand dark:bg-brand-dark rounded-lg px-md py-sm">
<Text className="text-brand-foreground dark:text-brand-dark-foreground font-semibold">
Get started
</Text>
</Pressable>
```
If the new color also needs to be reachable from non-`className` APIs (Paper, navigators, status bar), add a matching entry to `useThemeColors` so the rest of the template stays consistent.
---
## 7. Going Further
* [NativeWind documentation](https://www.nativewind.dev/) — class reference, advanced features (variants, animations).
* [Tailwind CSS documentation](https://tailwindcss.com/docs) — utility classes, responsive design, theming.
* [shadcn/ui](https://ui.shadcn.com/) — the design system the color tokens are inspired by.

BIN
docs/en/images/rn-home-screen.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
docs/en/images/rn-login-iphone.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 KiB

After

Width:  |  Height:  |  Size: 222 KiB

BIN
docs/en/images/rn-nav-comparison.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

12
docs/en/solution-templates/layered-web-application/mobile-applications.md

@ -100,6 +100,8 @@ You can follow [Mobile Application Development Tutorial - MAUI](../../tutorials/
This is the mobile application that is built based on Facebook's [React Native framework](https://reactnative.dev/) and [Expo](https://expo.dev/). It will be in the solution only if you've selected React Native as your mobile application option. This is the mobile application that is built based on Facebook's [React Native framework](https://reactnative.dev/) and [Expo](https://expo.dev/). It will be in the solution only if you've selected React Native as your mobile application option.
The UI is built with **[NativeWind v4](https://www.nativewind.dev/)** (Tailwind CSS for React Native) on top of a shadcn-inspired neutral palette, with full **light/dark mode** support. See [Styling with NativeWind](../../framework/ui/react-native/styling-with-nativewind.md) for the styling system reference.
#### Project Structure #### Project Structure
- **Environment.ts**: file using for provide application level variables like `apiUrl`, `oAuthConfig` and etc. - **Environment.ts**: file using for provide application level variables like `apiUrl`, `oAuthConfig` and etc.
@ -110,16 +112,20 @@ This is the mobile application that is built based on Facebook's [React Native f
- **contexts**: `contexts` folder contains [react context](https://react.dev/reference/react/createContext). You can expots your contexts in this folder. `Localization context provided in here` - **contexts**: `contexts` folder contains [react context](https://react.dev/reference/react/createContext). You can expots your contexts in this folder. `Localization context provided in here`
- **navigators**: folder contains [react-native stacks](https://reactnavigation.org/docs/stack-navigator/). After create new *FeatureName*Navigator we need to provide in `DrawerNavigator.tsx` file as `Drawer.Screen` - **hooks**: folder contains custom [React hooks](https://react.dev/reference/react/hooks) used across the app. The template ships with `useThemeColors` (theme-aware color values for components that can't use `className`) and `useLogout`, among others.
- **navigators**: folder contains [React Navigation](https://reactnavigation.org/) stacks. The template includes `BottomTabNavigator`, `DrawerNavigator`, `HomeNavigator`, `SettingsNavigator` and `AccountNavigator`. After creating a new *FeatureName*Navigator, register it in the appropriate parent navigator (e.g. `DrawerNavigator.tsx` or `BottomTabNavigator.tsx`).
- **screens**: is the content of navigated page. We'll pass as component property to [Stack.Screen](https://reactnavigation.org/docs/native-stack-navigator/) - **screens**: contains the content of each navigated page. The template ships with screens for `Home`, `Account`, `Settings`, `Login`, `Register`, `ForgotPassword`, `ResetPassword`, `ChangePassword` and `ProfilePicture`. Each screen is wired to a navigator as a [Stack.Screen](https://reactnavigation.org/docs/native-stack-navigator/) component.
- **store**: folder manages state-management operations. We will define `actions`, `listeners`, `reducers`, and `selectors` here. - **store**: folder manages state-management operations. We will define `actions`, `listeners`, `reducers`, and `selectors` here.
- **styles**: folder contains app styles. `system-style.ts` comes built in template we can also add new styles. - **theme**: folder exposes Paper-only theme colors used by `react-native-paper`'s `TextInput`. Most theming now lives in `tailwind.config.js` (see below).
- **utils**: folder contains helper functions that we can use in application - **utils**: folder contains helper functions that we can use in application
In addition to `src/`, the project root contains the NativeWind configuration: `tailwind.config.js` (design tokens, dark mode, color palette), `global.css` (Tailwind directives), `metro.config.js` and `babel.config.js` (NativeWind wiring), and `nativewind-env.d.ts` (TypeScript types for the `className` prop).
#### Running the Application #### Running the Application
React Native applications can't be run with the solution runner. You need to run them with the React Native CLI. You can check the [React Native documentation](https://reactnative.dev/docs/environment-setup) to learn how to setup the environment for React Native development. React Native applications can't be run with the solution runner. You need to run them with the React Native CLI. You can check the [React Native documentation](https://reactnative.dev/docs/environment-setup) to learn how to setup the environment for React Native development.

12
docs/en/solution-templates/microservice/mobile-applications.md

@ -145,6 +145,8 @@ You can follow [Mobile Application Development Tutorial - MAUI](../../tutorials/
This is the mobile application that is built based on Facebook's [React Native framework](https://reactnative.dev/) and [Expo](https://expo.dev/). It will be in the solution only if you've selected React Native as your mobile application option. This is the mobile application that is built based on Facebook's [React Native framework](https://reactnative.dev/) and [Expo](https://expo.dev/). It will be in the solution only if you've selected React Native as your mobile application option.
The UI is built with **[NativeWind v4](https://www.nativewind.dev/)** (Tailwind CSS for React Native) on top of a shadcn-inspired neutral palette, with full **light/dark mode** support. See [Styling with NativeWind](../../framework/ui/react-native/styling-with-nativewind.md) for the styling system reference.
#### Project Structure #### Project Structure
- **Environment.ts**: file using for providing application level variables like `apiUrl`, `oAuthConfig` and etc. - **Environment.ts**: file using for providing application level variables like `apiUrl`, `oAuthConfig` and etc.
@ -157,20 +159,22 @@ This is the mobile application that is built based on Facebook's [React Native f
- **hocs**: this folder is added to contain higher order components. The purpose is to wrap components with additional features or properties. It initially has a `PermissionHoc.tsx` that wraps a component to check the permission grant status. - **hocs**: this folder is added to contain higher order components. The purpose is to wrap components with additional features or properties. It initially has a `PermissionHoc.tsx` that wraps a component to check the permission grant status.
- **hooks**: covers the react native hooks where you can get a reference from [the official documentation](https://react.dev/reference/react/hooks). - **hooks**: covers the React Native hooks used across the app (see [the official documentation](https://react.dev/reference/react/hooks) for a reference). The template ships with `useThemeColors` (theme-aware color values for components that can't use `className`) and `useLogout`, among others.
- **interceptors**: initializes a file called `APIInterceptor.ts` that has a function to manage the http operations in a better way. - **interceptors**: initializes a file called `APIInterceptor.ts` that has a function to manage the http operations in a better way.
- **navigators**: folder contains [react-native stacks](https://reactnavigation.org/docs/stack-navigator/). After creating a new *FeatureName*Navigator we need to provide in `DrawerNavigator.ts` file as `Drawer.Screen` - **navigators**: folder contains [React Navigation](https://reactnavigation.org/) stacks. The template includes `BottomTabNavigator`, `DrawerNavigator`, `HomeNavigator`, `SettingsNavigator` and `AccountNavigator`. After creating a new *FeatureName*Navigator, register it in the appropriate parent navigator (e.g. `DrawerNavigator.tsx` or `BottomTabNavigator.tsx`).
- **screens**: folder has the content of navigated page. We will pass as component property to [Stack.Screen](https://reactnavigation.org/docs/native-stack-navigator/) - **screens**: contains the content of each navigated page. The template ships with screens for `Home`, `Account`, `Settings`, `Login`, `Register`, `ForgotPassword`, `ResetPassword`, `ChangePassword` and `ProfilePicture`. Each screen is wired to a navigator as a [Stack.Screen](https://reactnavigation.org/docs/native-stack-navigator/) component.
- **store**: folder manages state-management operations. We will define `actions`, `listeners`, `reducers`, and `selectors` here. - **store**: folder manages state-management operations. We will define `actions`, `listeners`, `reducers`, and `selectors` here.
- **styles**: folder contains app styles. `system-style.ts` comes built in template we can also add new styles. - **theme**: folder exposes Paper-only theme colors used by `react-native-paper`'s `TextInput`. Most theming now lives in `tailwind.config.js` (see below).
- **utils**: folder contains helper functions that we can use in application - **utils**: folder contains helper functions that we can use in application
In addition to `src/`, the project root contains the NativeWind configuration: `tailwind.config.js` (design tokens, dark mode, color palette), `global.css` (Tailwind directives), `metro.config.js` and `babel.config.js` (NativeWind wiring), and `nativewind-env.d.ts` (TypeScript types for the `className` prop).
#### Running the Application #### Running the Application
React Native applications can't be run with the solution runner. You need to run them with the React Native CLI. You can check the [React Native documentation](https://reactnative.dev/docs/environment-setup) to learn how to setup the environment for React Native development. React Native applications can't be run with the solution runner. You need to run them with the React Native CLI. You can check the [React Native documentation](https://reactnative.dev/docs/environment-setup) to learn how to setup the environment for React Native development.

Loading…
Cancel
Save