Include if for in Docs

This commit is contained in:
2026-03-26 14:59:31 +01:00
parent 90ff065f6d
commit 617a5d32c6
27 changed files with 338 additions and 37 deletions

View File

@@ -42,9 +42,11 @@ export default defineConfig({
{ text: 'Quick Start', link: '/api/quick' },
{ text: '$', link: '/api/signal' },
{ text: '$.watch', link: '/api/watch' },
{ text: '$.html', link: '/api/html' },
{ text: '$.if', link: '/api/if' },
{ text: '$.for', link: '/api/for' },
{ text: '$.router', link: '/api/router' },
{ text: '$.mount', link: '/api/mount' },
{ text: '$.html', link: '/api/html' },
{ text: 'Tags', link: '/api/tags' },
]
},

83
src/docs/api/for.md Normal file
View File

@@ -0,0 +1,83 @@
# ♻️ Reactive Lists: `$.for( )`
The `$.for` function is a high-performance list renderer. It maps an array (or a Signal containing an array) to DOM nodes. Unlike a simple `.map()`, `$.for` is **keyed**, meaning it only updates, moves, or deletes the specific items that changed.
## 🛠️ Function Signature
```typescript
$.for(
source: Signal<any[]> | Function | any[],
render: (item: any, index: number) => HTMLElement,
keyFn: (item: any, index: number) => string | number
): HTMLElement
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`source`** | `Signal` | Yes | The reactive array to iterate over. |
| **`render`** | `Function` | Yes | A function that returns a component or Node for each item. |
| **`keyFn`** | `Function` | Yes | A function to extract a **unique ID** for each item (crucial for performance). |
**Returns:** A `div` element with `display: contents` containing the live list.
---
## 📖 Usage Patterns
### 1. Basic Keyed List
Always use a unique property (like an `id`) as a key to ensure SigPro doesn't recreate nodes unnecessarily.
```javascript
const users = $([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
]);
Ul({ class: "list" }, [
$.for(users,
(user) => Li({ class: "p-2" }, user.name),
(user) => user.id
)
]);
```
### 2. Handling Primitive Arrays
If your array contains simple strings or numbers, you can use the value itself or the index as a key (though the index is less efficient for reordering).
```javascript
const tags = $(["Tech", "JS", "Web"]);
Div({ class: "flex gap-1" }, [
$.for(tags, (tag) => Badge(tag), (tag) => tag)
]);
```
---
## 🏗️ How it Works (The Reconciliation)
When the `source` signal changes, `$.for` performs the following steps:
1. **Key Diffing**: It compares the new keys with the previous ones stored in an internal `Map`.
2. **Node Reuse**: If a key already exists, the DOM node is **reused** and moved to its new position. No new elements are created.
3. **Cleanup**: If a key disappears from the list, SigPro calls `.destroy()` on that specific item's instance. This stops all its internal watchers and removes its DOM nodes.
---
## 💡 Performance Tips
* **Stable Keys**: Never use `Math.random()` as a key. This will force SigPro to destroy and recreate the entire list on every update, killing performance.
* **Component Encapsulation**: If each item in your list has its own complex internal state, `$.for` ensures that state is preserved even if the list is reordered, as long as the key remains the same.
---
## 🧪 Summary Comparison
| Feature | Standard `Array.map` | SigPro `$.for` |
| :--- | :--- | :--- |
| **Re-render** | Re-renders everything | Only updates changes |
| **DOM Nodes** | Re-created every time | **Reused via Keys** |
| **Memory** | Potential leaks | **Automatic Cleanup** |
| **State** | Lost on re-render | **Preserved per item** |

88
src/docs/api/if.md Normal file
View File

@@ -0,0 +1,88 @@
# 🔀 Reactive Branching: `$.if( )`
The `$.if` function is a reactive control flow operator. It manages the conditional rendering of components, ensuring that only the active branch exists in the DOM and in memory.
## 🛠️ Function Signature
```typescript
$.if(
condition: Signal<boolean> | Function,
thenVal: Component | Node,
otherwiseVal?: Component | Node
): HTMLElement
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`condition`** | `Signal` | Yes | A reactive source that determines which branch to render. |
| **`thenVal`** | `any` | Yes | The content to show when the condition is **truthy**. |
| **`otherwiseVal`** | `any` | No | The content to show when the condition is **falsy** (defaults to null). |
**Returns:** A `div` element with `display: contents` that acts as a reactive portal for the branches.
---
## 📖 Usage Patterns
### 1. Simple Toggle
The most common use case is showing or hiding a single element based on a state.
```javascript
const isVisible = $(false);
Div([
Button({ onclick: () => isVisible(!isVisible()) }, "Toggle Message"),
$.if(isVisible,
P("Now you see me!"),
P("Now you don't...")
)
]);
```
### 2. Lazy Component Loading
Unlike using a hidden class (CSS `display: none`), `$.if` is **lazy**. The branch that isn't active **is never created**. This saves memory and initial processing time.
```javascript
$.if(() => user.isLogged(),
() => Dashboard(), // Only executed if logged in
() => LoginGate() // Only executed if guest
)
```
---
## 🧹 Automatic Cleanup
One of the core strengths of `$.if` is its integrated **Cleanup** logic. SigPro ensures that when a branch is swapped out, it is completely purged.
1. **Stop Watchers**: All `$.watch` calls inside the inactive branch are permanently stopped.
2. **Unbind Events**: Event listeners attached via `$.html` are removed.
3. **Recursive Sweep**: SigPro performs a deep "sweep" of the removed branch to ensure no nested reactive effects remain active.
---
## 💡 Best Practices
* **Function Wrappers**: If your branches are heavy (e.g., they contain complex components), wrap them in a function `() => MyComponent()`. This prevents the component from being initialized until the condition actually meets its requirement.
* **Logical Expressions**: You can pass a complex computed function as the condition:
```javascript
$.if(() => count() > 10 && status() === 'ready',
Span("Threshold reached!")
)
```
---
## 🏗️ Technical Comparison
| Feature | Standard CSS `hidden` | SigPro `$.if` |
| :--- | :--- | :--- |
| **DOM Presence** | Always present | Only if active |
| **Reactivity** | Still processing in background | **Paused/Destroyed** |
| **Memory usage** | Higher | **Optimized** |
| **Cleanup** | Manual | **Automatic** |

View File

@@ -11,8 +11,8 @@ SigPro is a high-performance micro-framework that updates the **Real DOM** surgi
| **`$.watch(fn)`** | `(function) => stopFn` | **Automatic Mode:** Tracks any signal touched inside. Returns a stop function. |
| **`$.watch(deps, fn)`** | `(Array, function) => stopFn` | **Explicit Mode:** Only runs when signals in `deps` change. Used for Cleanup. |
| **`$.html(tag, props, kids)`** | `(string, obj, any) => Element` | The low-level DOM factory. Attaches `._cleanups` to every element. |
| **`$.If(cond, then, else?)`** | `(Signal, fn, fn?) => Node` | Reactive conditional. Automatically destroys the "else" branch memory. |
| **`$.For(list, itemFn)`** | `(Signal, fn) => Node` | Optimized list renderer. Manages individual item lifecycles. |
| **`$.if(cond, then, else?)`** | `(Signal, fn, fn?) => Node` | Reactive conditional. Automatically destroys the "else" branch memory. |
| **`$.for(list, itemFn)`** | `(Signal, fn) => Node` | Optimized list renderer. Manages individual item lifecycles. |
| **`$.router(routes)`** | `(Array) => Element` | Hash-based SPA router. Uses Explicit Watch to prevent memory leaks. |
| **`$.mount(node, target)`** | `(any, string\|Node) => Runtime` | Entry point. Creates a root instance with `.destroy()` capabilities. |