# Do's and Don'ts

Component patterns and coding conventions with clear examples. Use the rule numbers to reference guidelines in code reviews (e.g. "please follow Rule 1").

## Quick Reference

| # | Rule                                                 | Summary                                   |
| - | ---------------------------------------------------- | ----------------------------------------- |
| 1 | [Screens/Components](#rule-1-screenscomponents)      | No nested `screens/` folders              |
| 2 | [List/Detail Pattern](#rule-2-listdetail-pattern)    | Use `List` and `Detail` suffixes          |
| 3 | [Index.tsx Convention](#rule-3-indextsx-convention)  | One folder per component with `index.tsx` |
| 4 | [Component Names](#rule-4-component-names)           | Avoid redundant context in names          |
| 5 | [Utils Files](#rule-5-utils-files)                   | Use `utils/` folder at shared level       |
| 6 | [Components Nesting](#rule-6-components-nesting)     | Keep nested components with parent        |
| 7 | [Constants](#rule-7-constants)                       | Colocate or use `utils/constants/`        |
| 8 | [Import Preferences](#rule-8-import-preferences)     | Favor relative imports and TS aliases     |
| 9 | [useViewModel Pattern](#rule-9-useviewmodel-pattern) | Inject ViewModel as props                 |

---

## Rule 1: Screens/Components

Folders inside `screens/` cannot have their own `screens/` subfolders. If a component is uniquely associated with a screen, place it in a `components/` subfolder inside that screen folder.

> **Note:** **Do:**```
> Market/
> ├─ components/
> │  └─ MarketRowItem/
> └─ screens/
>    ├─ MarketList/
>    │  └─ components/
>    │     └─ BottomSection/
>    └─ MarketDetail/
> ```

> **Caution:** **Don't:**```
> Market/
> └─ screens/
>    ├─ MarketList/
>    │  └─ screens/      // ❌ No nested screens
>    └─ MarketDetail/
> ```

---

## Rule 2: List/Detail Pattern

- Suffix list components with `List` (always singular)
- Suffix detail components with `Detail`

> **Note:** **Do:**```
> Market/
> └─ screens/
>    ├─ MarketList/
>    └─ MarketDetail/
> ```

> **Caution:** **Don't:**```
> Market/
> └─ screens/
>    ├─ ListOfMarketItem/    // ❌ Wrong naming
>    └─ MarketItemPage/      // ❌ Wrong naming
> ```

---

## Rule 3: Index.tsx Convention

Create a dedicated folder per component and name the main file `index.tsx`.

> **Note:** **Do:**```
> components/
> └─ MarketRowItem/
>    ├─ index.tsx
>    └─ useMarketRowItemViewModel.tsx
> ```

> **Caution:** **Don't:**```
> components/
> ├─ MarketRowItem.tsx              // ❌ No folder
> └─ useMarketRowItemViewModel.tsx  // ❌ Outside component folder
> ```

---

## Rule 4: Component Names

Avoid redundant context in component names. The folder structure provides context.

> **Note:** **Do:**```
> features/Deposit/screens/SelectNetwork/useSelectNetworkViewModel.tsx
> ```

> **Caution:** **Don't:**```
> features/Deposit/screens/DepositFlowSelectNetwork/useDepositFlowSelectNetworkViewModel.tsx
> // ❌ "DepositFlow" is redundant - we're already in Deposit feature
> ```

---

## Rule 5: Utils Files

Do not colocate utils as a single file. Use a `utils/` folder and place it at the top level of components that import it.

> **Note:** **Do:**```
> Market/
> ├─ screens/
> │  └─ MarketDetail/
> ├─ components/
> │  ├─ Header/
> │  └─ Footer/
> └─ utils/
>    └─ index.tsx  // Shared by MarketDetail, Header, Footer
> ```

> **Caution:** **Don't:**```
> Market/
> └─ components/
>    └─ Header/
>       ├─ index.tsx
>       └─ utils.tsx  // ❌ Utils as sibling file
> ```

---

## Rule 6: Components Nesting

If a component is not reused elsewhere, create it next to its parent. Do not flatten nested components.

> **Note:** **Do:**```
> MarketDetail/
> ├─ components/
> │  └─ Stats/
> │     ├─ Price/
> │     │  └─ index.tsx
> │     ├─ Supply/
> │     │  └─ index.tsx
> │     └─ index.tsx
> └─ index.tsx
> ```

> **Caution:** **Don't:**```
> MarketDetail/
> ├─ Stats/
> │  └─ index.tsx
> ├─ Price/           // ❌ Flattened - unclear hierarchy
> │  └─ index.tsx
> ├─ Supply/          // ❌ Flattened - unclear hierarchy
> │  └─ index.tsx
> └─ index.tsx
> ```

---

## Rule 7: Constants

Colocate constants with their component. If shared between components, declare them in `utils/constants/`.

> **Note:** **Do:**```
> utils/
> └─ constants/
>    └─ coins.ts  // Shared by MarketDetail, MarketList, SendFlow
> ```

> **Caution:** **Don't:**```
> MarketDetail/
> ├─ coins.ts         // ❌ Local constant
> └─ index.tsx
>
> MarketList/
> └─ index.tsx        // Imports from ../MarketDetail/coins ❌
> ```

---

## Rule 8: Import Preferences

- **Favor relative imports** when not moving more than one folder up
- **Favor TS aliases** over absolute imports
- Add TS aliases when it improves readability

> **Note:** **Do:**```typescript
> import MarketDetail from "LLM/features/Market/screens/MarketDetail";
> import MarketDetail from "../MarketDetail";
> import MarketDetail from "./MarketDetail";
> ```

> **Caution:** **Don't:**```typescript
> import MarketDetail from "src/features/Market/screens/MarketDetail"; // ❌ Absolute path
> import MarketDetail from "../../../MarketDetail"; // ❌ Too many levels
> import MarketDetail from "./MarketDetail/index.tsx"; // ❌ Explicit index
> ```

---

## Rule 9: useViewModel Pattern

Inject the ViewModel hook result as props to the View component. Do not call the ViewModel hook inside the component body.

> **Note:** **Do:**```tsx
> // index.tsx - Inject ViewModel as props
> const MarketDetail = () => <View {...useMarketDetailViewModel()} />;
>
> // View.tsx - Receives pre-computed props
> const View = ({ price, volume, onRefresh }: Props) => (
>   <Screen>
>     <Text>{price}</Text>
>     <Text>{volume}</Text>
>     <Button onPress={onRefresh}>Refresh</Button>
>   </Screen>
> );
> ```

> **Caution:** **Don't:**```tsx
> // ❌ Don't call ViewModel inside the View component
> const MarketDetail = () => {
>   const { price, volume, onRefresh } = useMarketDetailViewModel();
>
>   return (
>     <Screen>
>       <Text>{price}</Text>
>       <Text>{volume}</Text>
>       <Button onPress={onRefresh}>Refresh</Button>
>     </Screen>
>   );
> };
> ```

> **Warning:** **Why?** Separating the ViewModel call from the View makes testing easier. You can test the View with different props without mocking hooks, and test the ViewModel logic independently.

---

## See also

- [MVVM Pattern](./mvvm-pattern) — Full ViewModel implementation pattern
- [Architecture](./architecture) — Folder structure and import rules
- [How to Structure a Feature](../how-to/structure-a-feature) — Applying these rules when creating features
