diff --git a/docs/assets/diagrams/di.svg b/docs/assets/diagrams/di.svg
new file mode 100644
index 0000000..c3349cb
--- /dev/null
+++ b/docs/assets/diagrams/di.svg
@@ -0,0 +1,32 @@
+
+
+
diff --git a/docs/assets/diagrams/reactivity.svg b/docs/assets/diagrams/reactivity.svg
new file mode 100644
index 0000000..f1800b3
--- /dev/null
+++ b/docs/assets/diagrams/reactivity.svg
@@ -0,0 +1,33 @@
+
+
+
diff --git a/docs/assets/diagrams/routing.svg b/docs/assets/diagrams/routing.svg
new file mode 100644
index 0000000..862e519
--- /dev/null
+++ b/docs/assets/diagrams/routing.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/docs/getting-started/architecture.md b/docs/getting-started/architecture.md
index f50f15d..1f806e9 100644
--- a/docs/getting-started/architecture.md
+++ b/docs/getting-started/architecture.md
@@ -1,163 +1,266 @@
-# ποΈ FletX Architecture
+# ποΈ FletX Architecture (Progressive Guide)
-FletX is built on a **modular and reactive architecture** designed to help developers structure Flet applications in a clean, maintainable, and scalable way. It is inspired by principles like separation of concerns and dependency injection.
+FletX is a **modular, reactive application layer** for [Flet](https://flet.dev). Think of it as the scaffolding that helps your UI, logic, and navigation work together cleanly.
+
+This guide builds up from the big picture to the details, with diagrams and tiny examples you can copy and adapt.
---
-## π Overview
+## πΊοΈ Big Picture
-FletX architecture revolves around three **core components**:
+Analogy: FletX is like a theater production.
-1. **Pages (`FletXPage`)** β declarative, reactive UI components.
-2. **Controllers (`FletXController`)** β business logic and state management.
-3. **Services (optional)** β reusable utilities for API calls, database access, etc.
+- The **Page** is the stage where the scene is rendered.
+- The **Controller** is the director that decides what happens next.
+- **Reactive state (Rx)** is the script prompts: when a line changes, actors (widgets) immediately react.
+- **Services** are backstage crews (API, storage, utilities).
+- The **Router** is the stage manager who swaps scenes.
----
+High-level flow:
+
+```text
+User action β Controller updates reactive state β Widgets re-render
+```
-### π Typical Flow
+
+
+ Reactivity flow: events update reactive state; bound widgets re-render automatically.
+
-A typical user interaction flows like this:
+Navigation flow:
-```plaintext
-User Action β Controller Logic β State Update β UI Re-render
+```text
+Route change β Page created β Controller available β build() renders UI
```
-When routing/navigation happens, it flows like this:
+
+
+ Routing flow: router matches URL, creates the page, attaches its controller, then renders.
+
-```plaintext
-Routing β Page Instantiation β Controller Injection β Build UI
-```
+!!! tip "How to read these diagrams"
+
+ - Boxes represent **components** (Page, Controller, Service, etc.).
+ - Arrows indicate **direction of flow** (events β state β UI).
+ - Bold labels are the **key step** in each stage.
+ - White diagram backgrounds ensure legibility in **dark mode**; use the ASCII diagrams alongside if you prefer text.
---
-## π§± Core Building Blocks
+## π§± Core Pieces (at a glance)
-### 1. FletXPage
+- Page (`FletXPage`): builds UI in `build()` and accesses its controller via `self.ctrl` (or any variable name you choose).
+- Controller (`FletXController`): holds logic and reactive state (e.g., `RxInt`, `RxStr`).
+- Services (optional): reusable dependencies resolved via DI (dependency injection).
+- Router (`router_config`): maps paths to pages; supports dynamic params and guards.
-A **FletXPage** is a class that represents a visual page (screen) in your app. It inherits from `FletXPage` and defines a `build()` method that returns a reactive Flet UI.
+Simple data flow:
-#### Example:
+```text
+[Widget event] βββΆ [Controller method] βββΆ [Rx value changes] βββΆ [UI auto-updates]
+```
+
+---
+
+## β First Contact: 30βsecond example
```python
-class HomePage(FletXPage):
- ctrl = HomeController()
+import flet as ft
+from fletx.core import FletXPage, FletXController, RxInt
+from fletx.decorators import obx
+
+class CounterController(FletXController):
+ def __init__(self):
+ self.count = RxInt(0)
+ super().__init__()
+
+class CounterPage(FletXPage):
+ ctrl = CounterController() # 'ctrl' is a convention; you can name it anything
+
+ @obx
+ def counter_text(self):
+ return ft.Text(f"Count: {self.ctrl.count.value}", size=40)
def build(self):
return ft.Column([
- ft.Text(lambda: str(self.ctrl.counter()), size=40),
- ft.ElevatedButton("Increment", on_click=lambda e: self.ctrl.counter.increment())
+ self.counter_text(),
+ ft.ElevatedButton("+1", on_click=lambda e: self.ctrl.count.increment())
])
```
+What to notice:
+
+- The `@obx` decorator makes the method reactive β it re-renders when `count` changes.
+- The button calls a controller method that mutates reactive state.
+- `ctrl` is just a variable name; you can use any name you prefer.
+
---
-### 2. FletXController
+## π Reactivity (how updates propagate)
+
+```text
+ increment()
+ β
+ βΌ
+ [RxInt.count] ββ change detected βββΆ widgets depending on it re-render
+```
+
+Key ideas:
-A **FletXController** handles **business logic**, manages **reactive state**, and is tied to a specific page. It uses observable values to trigger UI updates automatically.
+- Use `Rx*` types (`RxInt`, `RxStr`, `RxList`, `RxDict`, β¦) for observable state.
+- Use `@obx` decorator or reactive decorators so widgets update automatically.
+- Keep computations inside the controller; keep the page mostly declarative.
-#### Example:
+Tiny example:
```python
-class HomeController(FletXController):
+from fletx.core import FletXController, RxStr
+
+class HelloController(FletXController):
def __init__(self):
- self.counter = RxInt(0)
+ self.name = RxStr("World")
super().__init__()
+
+ def set_name(self, value: str):
+ self.name.value = value.strip() or "World"
```
-`RxInt` is a reactive object provided by FletX. Updating it automatically refreshes all widgets that depend on it.
+```python
+import flet as ft
+from fletx.core import FletXPage
+from fletx.decorators import obx
+
+class HelloPage(FletXPage):
+ ctrl = HelloController()
+
+ @obx
+ def greeting(self):
+ return ft.Text(f"Hello, {self.ctrl.name.value}!")
+
+ def build(self):
+ return ft.Column([
+ self.greeting(),
+ ft.TextField(on_change=lambda e: self.ctrl.set_name(e.control.value))
+ ])
+```
---
-## π Navigation & Routing
+## π§ Routing (moving between pages)
-FletX provides a centralized router configuration (`router_config`) for managing navigation across your app:
+Basic setup:
```python
-router_config.add_route("/", HomePage)
-router_config.add_route("/about", AboutPage)
+from fletx.app import FletXApp
+from fletx.navigation import router_config
-# Or register a list of routes
router_config.add_routes([
{"path": "/", "component": HomePage},
- {"path": "/settings", "component": SettingsPage}
+ {"path": "/user/:id", "component": UserPage},
])
+
+app = FletXApp(title="My App", initial_route="/")
+app.run()
```
-> You can define dynamic routes like:
+Access dynamic params inside a page:
```python
-router_config.add_route("/user/:id", UserPage)
-router_config.add_route("/user/*category", CategoryPage)
+class UserPage(FletXPage):
+ ctrl = UserController()
+
+ def build(self):
+ user_id = self.route_info.params["id"]
+ # render with user_id
```
-In your page:
+Diagram:
-```python
-def build(self):
- user_id = self.route_info.params["id"]
+```text
+URL change β match route β create Page β attach Controller β build() β UI
```
----
+Learn more: see `Getting Started β Routing System` and `Pages (views)`.
-## π§ Reactive State Management
+---
-FletX provides **reactive variables**: `RxInt`, `RxStr`, `RxList`, etc., which track their values and trigger UI updates when modified.
+## π§© Dependency Injection (Services and reuse)
-#### Example:
+Analogy: DI is a tool bench. Controllers donβt build the tools; they pick them up.
```python
-class CounterController(FletXController):
+class UserService:
+ def fetch_user(self, user_id: str) -> dict:
+ return {"id": user_id, "name": "Jane"}
+
+# Register the service with DI container (typically in main.py or app setup)
+from fletx.core import FletX
+FletX.put(UserService) # Register as singleton
+
+class UserController(FletXController):
def __init__(self):
- self.count = RxInt(0)
+ self.user_service = FletX.find(UserService)
+ self.user = RxDict({})
super().__init__()
-class CounterPage(FletXPage):
- ctrl = CounterController()
+ def load_user(self, user_id: str):
+ self.user.value = self.user_service.fetch_user(user_id)
+```
- def build(self):
- return MyReactiveText(rx_text=self.ctrl.count, size=200, weight="bold"),
+DI flow:
+
+```text
+[Controller] ββasksβββΆ [DI container] ββreturnsβββΆ [Service instance]
```
-> `lambda:` makes the widget reactive β it will re-render automatically when the value changes.
+
+
+ Dependency Injection: controllers ask the container for services instead of constructing them.
+
+
+Learn more: see `Getting Started β Dependency Injection` and `Services`.
---
-## π§© Services (Optional)
+## π£ EndβtoβEnd Mini Walkthrough
-**Services** are reusable, testable classes used for accessing APIs, databases, or any shared logic. They can be injected into controllers.
+Goal: Tap a button on `CounterPage` to increment a number.
-#### Example:
+1) Router maps `/` β `CounterPage`.
+2) `CounterPage` is created with `ctrl = CounterController()`.
+3) UI shows a `Text(lambda: ...)` bound to `ctrl.count`.
+4) Button calls `ctrl.count.increment()`.
+5) `RxInt` notifies dependents β `Text` re-renders with the new value.
-```python
-class UserService:
- def fetch_user(self, user_id):
- return {"id": user_id, "name": "John Doe"}
-```
-
-Used in a controller:
+---
-```python
-class UserController(FletXController):
- def __init__(self):
- self.user_service = FletX.find(UserService)
- self.user = RxDict({})
- super().__init__()
+## π§° Common Patterns
- def load_user(self, user_id):
- self.user.value = self.user_service.fetch_user(user_id)
-```
+- Keep pages thin; put logic in controllers.
+- Use services for I/O and reuse (API, storage, computation helpers).
+- Prefer small, focused controllers per page/feature.
+- Derive view state from a few reactive primitives to avoid duplication.
+- Use route params to load data in `on_init`/first build.
---
-## π§ͺ Minimal Architecture Example
+## β
Best Practices
+
+- Name reactive variables by intent (e.g., `isLoading`, `selectedUserId`).
+- Avoid mutating raw data in pages; call controller methods instead.
+- Keep `build()` pure; it should read state and declare UI, not perform side-effects.
+- Debounce or throttle controller methods that respond to rapid UI events.
+- Centralize navigation in controller methods for testability.
+- Guard your routes when needed (auth, permissions).
+
+---
-Hereβs a minimal FletX app putting all the pieces together:
+## π§ͺ Minimal App Template
```python
# main.py
from fletx.app import FletXApp
from fletx.navigation import router_config
-from .pages.counter import CounterPage
router_config.add_route("/", CounterPage)
@@ -167,47 +270,44 @@ app.run()
```python
# pages/counter.py
-from fletx.core import FletXPage
-from .controllers.counter import CounterController
-from .components.reactive_text import MyReactiveText
import flet as ft
+from fletx.core import FletXPage, FletXController, RxInt
+from fletx.decorators import obx
+
+class CounterController(FletXController):
+ def __init__(self):
+ self.count = RxInt(0)
+ super().__init__()
class CounterPage(FletXPage):
ctrl = CounterController()
+ @obx
+ def count_display(self):
+ return ft.Text(f"{self.ctrl.count.value}", size=40)
+
def build(self):
return ft.Column([
- MyReactiveText(rx_text=self.ctrl.count, size=40, weight="bold"),
- ft.ElevatedButton("Increment", on_click=lambda e: self.ctrl.count.increment())
+ self.count_display(),
+ ft.ElevatedButton("Increment", on_click=lambda e: self.ctrl.count.increment()),
])
```
-```python
-# components/reactive_text.py
-import flet as ft
-from fletx.decorators import simple_reactive
-
-@simple_reactive(bindings={'value': 'text'})
-class MyReactiveText(ft.Text):
-
- def __init__(self, rx_text: RxStr, **kwargs):
- self.text: RxStr = rx_text
- super().__init__(**kwargs)
-```
+---
-```python
-# controllers/counter.py
-from fletx.core import FletXController, RxInt
+## π Where to go next
-class CounterController(FletXController):
- def __init__(self):
- self.count = RxInt(0)
- super().__init__()
-```
+- Getting Started β `Pages (views)`
+- Getting Started β `Controllers`
+- Getting Started β `Routing System`
+- Getting Started β `State Management`
+- Getting Started β `Dependency Injection`
+- Sample project: `Getting Started β Sample Project`
+- Real-world example: [Fake Shop E-commerce App](https://github.com/AllDotPy/fake-shop)
---
-## β
Summary Table
+## π Reference Cheatsheet
| Component | Responsibility |
| ----------------- | ---------------------------------------- |
@@ -215,13 +315,4 @@ class CounterController(FletXController):
| `FletXController` | Holds business logic and reactive state |
| `Rx*` objects | Reactive state (trigger UI rebuilds) |
| `router_config` | Defines app navigation routes |
-| Services | Shared utilities for APIs, storage, etc. |
-
-
----
-
-## π§ Next Steps
-
-* Explore [reactive UI binding](ui/reactivity.md)
-* Learn about the [Architecture](architecture.md)
-* Dive into [dependency injection](guides/dependency-injection.md)
\ No newline at end of file
+| Services | Shared utilities for APIs, storage, etc. |
\ No newline at end of file
diff --git a/docs/getting-started/routing.md b/docs/getting-started/routing.md
index 44c0d6c..5f498e5 100644
--- a/docs/getting-started/routing.md
+++ b/docs/getting-started/routing.md
@@ -6,6 +6,14 @@ FletX also provides utility functions for programmatic navigation, such as `navi
---
+!!! tip "How to read routing diagrams"
+
+ - Boxes represent **router steps** or **components**.
+ - Arrows indicate **navigation flow** (URL β match β page β controller β UI).
+ - Prefer using the Architecture guideβs diagrams as a quick mental model.
+
+[β Back to Architecture](architecture.md)
+
## π§ Basic Routing
Use the global `router_config` to define your app's navigation structure:
@@ -268,5 +276,5 @@ go_back()
## π§ Next Steps
* Dive into [dependency injection](dependency-injection.md)
-* Explore the [sevices](services.md)
+* Explore the [services](services.md)
* Learn about the [Architecture](architecture.md)
\ No newline at end of file
diff --git a/docs/getting-started/state-management.md b/docs/getting-started/state-management.md
index e121965..cb4ee6c 100644
--- a/docs/getting-started/state-management.md
+++ b/docs/getting-started/state-management.md
@@ -4,6 +4,16 @@
---
+!!! tip "How to read reactivity diagrams"
+
+ - Boxes are **state holders** (Rx) or **consumers** (widgets/controllers).
+
+ - Arrows show **state change propagation**.
+
+ - Use the Architecture guideβs reactivity figure as a companion visual.
+
+[β Back to Architecture](architecture.md)
+
### π Why reactivity matters
In most frameworks, when a value changes (e.g. a user logs in), you need to manually update the UI, synchronize the state, or refresh components.