diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 56079eb813..f82f29d551 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -1935,6 +1935,10 @@ "text": "Overview", "path": "framework/ui/react-native", "isIndex": true + }, + { + "text": "Styling with NativeWind", + "path": "framework/ui/react-native/styling-with-nativewind.md" } ] }, diff --git a/docs/en/framework/ui/react-native/index.md b/docs/en/framework/ui/react-native/index.md index 92b7c0815d..c0957d5426 100644 --- a/docs/en/framework/ui/react-native/index.md +++ b/docs/en/framework/ui/react-native/index.md @@ -18,7 +18,7 @@ The ABP platform provides a basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated with your ABP-based backends**. -React Native gif +> 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. ## How to Prepare Development Environment @@ -128,19 +128,85 @@ In the image above, you can start the application on an Android emulator, an iOS ### Expo -React Native login screen on iPhone 16 +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 1. Start the emulator in **Android Studio** before running the `yarn start` or `npm start` command. 2. Press **a** to open in Android Studio. -React Native login screen on Android Device +React Native login screen 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. +## 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**. + +Bottom Tab vs Drawer navigation comparison + + +Every main tab or drawer item is wired to **its own** native stack (`@react-navigation/native-stack`). Pushing more screens stays on that branch: the Back stack belongs to that tab or drawer route and does not mix with others. Bottom Tab and Drawer use the **same screen components**; they differ in how those screens are grouped and opened from the outer shell (and where the sign‑in/sign‑up flow lives in Bottom Tab versus Drawer). + +> **How to choose:** The mode is selected in **ABP Studio** during the *Mobile Framework* step. Switching modes after the project is generated is not a one-line change — you would need to add the missing navigator (and its `@react-navigation/drawer` or `@react-navigation/bottom-tabs` dependency) manually, then update `src/AppContainer.tsx` and `src/navigators/types.ts` to match. Pick the mode upfront when possible. + +### 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//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) > React Native application does not trust the auto-generated .NET HTTPS certificate. You should use **HTTP** during the development. diff --git a/docs/en/framework/ui/react-native/styling-with-nativewind.md b/docs/en/framework/ui/react-native/styling-with-nativewind.md new file mode 100644 index 0000000000..2f2b8e75fa --- /dev/null +++ b/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). + +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 (`/// `) 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 + + + Hello + + +``` + +> **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. + +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 + + + Get started + + +``` + +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. diff --git a/docs/en/get-started/images/abp-studio-mobile-sample.gif b/docs/en/get-started/images/abp-studio-mobile-sample.gif index 4301c451b6..2a165b9900 100644 Binary files a/docs/en/get-started/images/abp-studio-mobile-sample.gif and b/docs/en/get-started/images/abp-studio-mobile-sample.gif differ diff --git a/docs/en/images/rn-home-screen.png b/docs/en/images/rn-home-screen.png new file mode 100644 index 0000000000..cc01a2a6d2 Binary files /dev/null and b/docs/en/images/rn-home-screen.png differ diff --git a/docs/en/images/rn-login-iphone.png b/docs/en/images/rn-login-iphone.png index 576c260f5e..7bc468584e 100644 Binary files a/docs/en/images/rn-login-iphone.png and b/docs/en/images/rn-login-iphone.png differ diff --git a/docs/en/images/rn-nav-comparison.png b/docs/en/images/rn-nav-comparison.png new file mode 100644 index 0000000000..02fe01a6f7 Binary files /dev/null and b/docs/en/images/rn-nav-comparison.png differ diff --git a/docs/en/solution-templates/layered-web-application/mobile-applications.md b/docs/en/solution-templates/layered-web-application/mobile-applications.md index 553064284f..bf2e6375ae 100644 --- a/docs/en/solution-templates/layered-web-application/mobile-applications.md +++ b/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. +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 - **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` -- **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**: custom [React hooks](https://react.dev/reference/react/hooks) for shared UI and app logic. For example, `useThemeColors` returns light/dark palette values when a component needs explicit colors instead of NativeWind `className`, and `useLogout` handles signing out—plus other hooks bundled with the template. + +- **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. -- **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 +In addition to `src/`, the project root hosts the NativeWind setup. `tailwind.config.js` defines design tokens, the color palette, and dark mode. `global.css` contains Tailwind's layer directives. `metro.config.js` and `babel.config.js` configure Metro and Babel so NativeWind can transform your styles. `nativewind-env.d.ts` adds TypeScript typings for the `className` prop on components. + #### 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. diff --git a/docs/en/solution-templates/microservice/mobile-applications.md b/docs/en/solution-templates/microservice/mobile-applications.md index c14895b7b9..aab9b9a5f9 100644 --- a/docs/en/solution-templates/microservice/mobile-applications.md +++ b/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. +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 - **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. -- **hooks**: covers the react native hooks where you can get a reference from [the official documentation](https://react.dev/reference/react/hooks). +- **hooks**: Custom [React hooks](https://react.dev/reference/react/hooks) for shared UI and app logic. For example, `useThemeColors` returns light/dark palette values when a component needs explicit colors instead of NativeWind `className`, and `useLogout` handles signing out—plus other hooks bundled with the template. - **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. -- **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 +In addition to `src/`, the project root hosts the NativeWind setup. `tailwind.config.js` defines design tokens, the color palette, and dark mode. `global.css` contains Tailwind's layer directives. `metro.config.js` and `babel.config.js` configure Metro and Babel so NativeWind can transform your styles. `nativewind-env.d.ts` adds TypeScript typings for the `className` prop on components. + #### 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.