This commit is contained in:
2026-03-26 14:06:49 +01:00
parent adfe628dfd
commit 876874c2f0
51 changed files with 535 additions and 967 deletions

View File

@@ -41,9 +41,7 @@ export default defineConfig({
items: [
{ text: 'Quick Start', link: '/api/quick' },
{ text: '$', link: '/api/signal' },
{ text: '$.effect', link: '/api/effect' },
{ text: '$.ignore', link: '/api/ignore' },
{ text: '$.view', link: '/api/view' },
{ text: '$.watch', link: '/api/watch' },
{ text: '$.html', link: '/api/html' },
{ text: '$.router', link: '/api/router' },
{ text: '$.mount', link: '/api/mount' },

View File

@@ -1,90 +0,0 @@
# ⚡ Side Effects: `$.effect( )`
The `$.effect` function allows you to run a piece of code whenever the signals it depends on are updated. It automatically tracks any signal called within its body.
## 🛠 Function Signature
```typescript
$.effect(callback: Function): StopFunction
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`callback`** | `Function` | Yes | The code to run. It will execute immediately and then re-run on dependency changes. |
**Returns:** A `StopFunction` that, when called, cancels the effect and prevents further executions.
---
## 📖 Usage Patterns
### 1. Basic Tracking
Any signal you "touch" inside the effect becomes a dependency.
```javascript
const count = $(0);
$.effect(() => {
// This runs every time 'count' changes
console.log(`The count is now: ${count()}`);
});
count(1); // Console: "The count is now: 1"
```
### 2. Manual Cleanup
If your effect creates something that needs to be destroyed (like a timer or a global event listener), you can return a cleanup function.
```javascript
$.effect(() => {
const timer = setInterval(() => console.log("Tick"), 1000);
// SigPro will run this BEFORE the next effect execution
// or when the effect is stopped.
return () => clearInterval(timer);
});
```
### 3. Nesting & Automatic Cleanup
If you create a signal or another effect inside an effect, SigPro tracks them as "children". When the parent effect re-runs or stops, all children are automatically cleaned up to prevent memory leaks.
```javascript
$.effect(() => {
if (isLoggedIn()) {
// This sub-effect is only active while 'isLoggedIn' is true
$.effect(() => {
console.log("Fetching user data...");
});
}
});
```
---
## 🛑 Stopping an Effect
You can stop an effect manually by calling the function it returns. This is useful for one-time operations or complex logic.
```javascript
const stop = $.effect(() => {
console.log(count());
});
// Later...
stop(); // The effect is destroyed and will never run again.
```
---
## 💡 Pro Tip: Batching
SigPro uses a **Microtask Queue** to handle updates. If you update multiple signals at once, the effect will only run **once** at the end of the current task.
```javascript
const a = $(0);
const b = $(0);
$.effect(() => console.log(a(), b()));
// This triggers only ONE re-run, not two.
a(1);
b(2);
```

View File

@@ -1,6 +1,6 @@
# 🏗️ The DOM Factory: `$.html( )`
`$.html` is the internal engine that creates, attributes, and attaches reactivity to DOM elements. It is the foundation for all Tag Constructors in SigPro.
`$.html` is the internal engine that creates, attributes, and attaches reactivity to DOM elements. In V2, it uses `$.watch` to maintain a live, high-performance link between your Signals and the Document Object Model.
## 🛠 Function Signature
@@ -41,7 +41,7 @@ $.html("button", {
```
### 3. Reactive Attributes
If an attribute value is a **function** (like a Signal), `$.html` creates an internal `$.effect` to keep the DOM in sync with the state.
If an attribute value is a **function** (like a Signal), `$.html` creates an internal **`$.watch`** to keep the DOM in sync with the state.
```javascript
$.html("div", {
@@ -51,7 +51,7 @@ $.html("div", {
```
### 4. Reactive Children
Children can be static or dynamic. When a child is a function, SigPro creates a reactive boundary for that specific part of the DOM.
Children can be static or dynamic. When a child is a function, SigPro creates a reactive boundary using `$.watch` for that specific part of the DOM.
```javascript
$.html("div", {}, [
@@ -74,9 +74,10 @@ $.html("input", {
});
```
## 🧹 Automatic Cleanup
Every element created with `$.html` gets a hidden `._cleanups` property (a `Set`).
* When SigPro removes an element via `$.view` or `$.router`, it automatically executes all functions stored in this Set (stopping effects, removing listeners, etc.).
## 🧹 Memory Management (Internal)
Every element created with `$.html` is "self-aware" regarding its reactive dependencies.
* **`._cleanups`**: A hidden `Set` attached to the element that stores all `stop()` functions from its internal `$.watch` calls and event listeners.
* **Lifecycle**: When an element is removed by a Controller (`$.If`, `$.For`, or `$.router`), SigPro performs a recursive "sweep" to execute these cleanups, ensuring **zero memory leaks**.
---

View File

@@ -1,75 +0,0 @@
# 🛑 Untracking: `$.ignore( )`
The `$.ignore` function allows you to read a signal's value inside an effect or a computed signal **without** creating a dependency.
## 🛠 Function Signature
```typescript
$.ignore(callback: Function): any
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`callback`** | `Function` | Yes | A function where signals can be read "silently". |
**Returns:** Whatever the callback function returns.
---
## 📖 Usage Patterns
### 1. Preventing Dependency Tracking
Normally, reading a signal inside `$.effect` makes the effect re-run when that signal changes. `$.ignore` breaks this link.
```javascript
const count = $(0);
const logLabel = $("System Log");
$.effect(() => {
// This effect tracks 'count'...
const currentCount = count();
// ...but NOT 'logLabel'.
// Changing 'logLabel' will NOT re-run this effect.
const label = $.ignore(() => logLabel());
console.log(`${label}: ${currentCount}`);
});
count(1); // Console: "System Log: 1" (Triggers re-run)
logLabel("UI"); // Nothing happens in console (Ignored)
```
### 2. Reading State in Event Handlers
Inside complex UI logic, you might want to take a "snapshot" of a signal without triggering a reactive chain.
```javascript
const handleClick = () => {
// Accessing state without letting the caller know we touched it
const data = $.ignore(() => mySignal());
process(data);
};
```
### 3. Avoiding Infinite Loops
If you need to **write** to a signal based on its own value inside an effect (and you aren't using the functional updater), `$.ignore` prevents the effect from triggering itself.
```javascript
$.effect(() => {
const value = someSignal();
if (value > 100) {
// We update the signal, but we ignore the read to avoid a loop
$.ignore(() => someSignal(0));
}
});
```
---
## 💡 Why use it?
* **Performance:** Prevents expensive effects from running when non-essential data changes.
* **Logic Control:** Allows "sampling" a signal at a specific point in time.
* **Safety:** Essential for complex state orchestrations where circular dependencies might occur.

View File

@@ -1,8 +1,8 @@
# 🔌 Application Mounter: `$.mount( )`
The `$.mount` function is the entry point of your reactive world. It bridges the gap between your SigPro logic and the browser's Real DOM by injecting a component into the document.
The `$.mount` function is the entry point of your reactive world. It bridges the gap between your SigPro logic and the browser's Real DOM by injecting a component into the document and initializing its reactive lifecycle.
## 1. Function Signature
## 🛠️ Function Signature
```typescript
$.mount(node: Function | HTMLElement, target?: string | HTMLElement): RuntimeObject
@@ -13,100 +13,73 @@ $.mount(node: Function | HTMLElement, target?: string | HTMLElement): RuntimeObj
| **`node`** | `Function` or `Node` | **Required** | The component function or DOM element to render. |
| **`target`** | `string` or `Node` | `document.body` | CSS selector or DOM element where the app will live. |
**Returns:** A `Runtime` object containing the `container` and a `destroy()` method.
**Returns:** A `Runtime` object containing the `container` and a `destroy()` method to wipe all reactivity and DOM nodes.
---
## 2. Common Usage Scenarios
## 📖 Common Usage Scenarios
### A. The "Clean Slate" (SPA Entry)
In a modern Single Page Application, you typically want SigPro to manage the entire view. By default, if no target is provided, it mounts to `document.body`.
### 1. The SPA Entry Point
In a Single Page Application, you typically mount your main component to the body or a root div. SigPro manages the entire view from that point.
```javascript
import { $ } from './sigpro.js';
import App from './App.js';
// Mounts your main App component directly to the body
$.mount(App);
// Mounts your main App component
$.mount(App, '#app-root');
```
### B. Targeting a Specific Container
If your HTML has a predefined structure, you can tell SigPro exactly where to render by passing a CSS selector or a direct reference.
```html
<div id="sidebar"></div>
<main id="app-root"></main>
```
### 2. Reactive "Islands"
SigPro is perfect for adding reactivity to static pages. You can mount small widgets into specific parts of an existing HTML layout.
```javascript
// Mount using a CSS selector
$.mount(MyComponent, '#app-root');
// Mount using a direct DOM reference
const sidebar = document.querySelector('#sidebar');
$.mount(SidebarComponent, sidebar);
```
### C. Creating "Reactive Islands"
SigPro is excellent for "sprinkling" reactivity onto legacy or static pages. You can inject small reactive widgets into any part of an existing HTML layout.
```javascript
// A small reactive widget
const CounterWidget = () => {
const Counter = () => {
const count = $(0);
return Button({ onclick: () => count(c => c + 1) }, [
"Clicks: ", count
]);
};
// Mount it into a specific div in your static HTML
$.mount(CounterWidget, '#counter-container');
// Mount only the counter into a specific sidebar div
$.mount(Counter, '#sidebar-widget');
```
---
## 3. How it Works (Lifecycle)
## 🔄 How it Works (Lifecycle & Saneamiento)
When `$.mount` is executed, it performs these critical steps:
When `$.mount` is executed, it performs these critical steps to ensure a leak-free environment:
1. **Resolution & Wrapping**: If you pass a **Function**, SigPro wraps it in a `$.view()`. This starts tracking all internal signals and effects.
2. **Target Clearance**: It uses `target.replaceChildren()`. This efficiently wipes any existing HTML or "zombie" nodes inside the target before mounting.
3. **Injection**: The component's container is appended to the target.
4. **Memory Management**: It stores the `Runtime` instance associated with that DOM element. If you call `$.mount` again on the same target, SigPro automatically **destroys the previous app** to prevent memory leaks.
1. **Duplicate Detection**: If you call `$.mount` on a target that already has a SigPro instance, it automatically calls `.destroy()` on the previous instance. This prevents "Zombie Effects" from stacking in memory.
2. **Internal Scoping**: It executes the component function inside an internal **Reactive Owner**. This captures every `$.watch` and event listener created during the render.
3. **Target Injection**: It clears the target using `replaceChildren()` and appends the new component.
4. **Runtime Creation**: It returns a control object:
* `container`: The actual DOM element created.
* `destroy()`: The "kill switch" that runs all cleanups, stops all watchers, and removes the element from the DOM.
---
## 4. Global vs. Local Scope
## 🛑 Manual Unmounting
### The "Framework" Way (Global)
By importing your core in your entry file, SigPro automatically initializes global Tag Constructors (`Div`, `Span`, `H1`, etc.). This allows for a clean, declarative DX across your entire project.
While SigPro handles most cleanups automatically (via `$.If`, `$.For`, and `$.router`), you can manually destroy any mounted instance. This is vital for imperatively managed UI like **Toasts** or **Modals**.
```javascript
// main.js
import './sigpro.js';
const instance = $.mount(MyToast, '#toast-container');
// Now any file can simply do:
$.mount(() => H1("Global SigPro App"));
```
### The "Library" Way (Local)
If you prefer to avoid global variables, you can use the low-level `$.html` factory to create elements locally.
```javascript
import { $ } from './sigpro.js';
const myNode = $.html('div', { class: 'widget' }, 'Local Instance');
$.mount(myNode, '#widget-target');
// Later, to remove the toast and kill its reactivity:
instance.destroy();
```
---
## 5. Summary Cheat Sheet
## 💡 Summary Cheat Sheet
| Goal | Code Pattern |
| :--- | :--- |
| **Mount to body** | `$.mount(App)` |
| **Mount to ID** | `$.mount(App, '#root')` |
| **Mount to Element** | `$.mount(App, myElement)` |
| **Mount raw Node** | `$.mount(Div("Hello"), '#id')` |
| **Unmount/Destroy** | `const app = $.mount(App); app.destroy();` |
| **Mount to CSS Selector** | `$.mount(App, '#root')` |
| **Mount to DOM Node** | `$.mount(App, myElement)` |
| **Clean & Re-mount** | Calling `$.mount` again on the same target |
| **Total Saneamiento** | `const app = $.mount(App); app.destroy();` |

View File

@@ -1,6 +1,6 @@
# 🎨 Global Tag Helpers
In **SigPro**, you don't need to manually type `$.html('div', ...)` for every element. To keep your code declarative and readable, the engine automatically generates **Global Helper Functions** for all standard HTML5 tags upon initialization.
In **SigPro V2**, you don't need to manually type `$.html('div', ...)` for every element. To keep your code declarative and readable, the engine automatically generates **Global Helper Functions** for all standard HTML5 tags upon initialization.
## 1. How it Works
@@ -59,23 +59,23 @@ Span(42);
---
## 4. Reactive Power Examples
## 4. Reactive Power V2
These helpers are natively wired into SigPro's reactivity. No manual `useEffect` or `watch` calls are needed.
These helpers are natively wired into SigPro's **`$.watch`** engine. No manual effect management is needed; the lifecycle is tied to the DOM node.
### Reactive Attributes
Simply pass a Signal (function) to any attribute. SigPro handles the rest.
Simply pass a Signal (function) to any attribute. SigPro creates an internal `$.watch` to keep the DOM in sync.
```javascript
const theme = $("light");
Div({
// Updates 'class' automatically when theme() changes
// Updates 'class' automatically via internal $.watch
class: () => `app-box ${theme()}`
}, "Themeable Box");
```
### The Binding Operator (`$`)
Use the `$` prefix for **Two-Way Binding** on inputs.
Use the `$` prefix for **Two-Way Binding** on inputs. This bridges the Signal and the Input element bi-directionally.
```javascript
const search = $("");
@@ -86,13 +86,13 @@ Input({
});
```
### Dynamic Lists
Combine tags with `ui.For` for high-performance list rendering.
### Dynamic Flow & Saneamiento
Combine tags with Core controllers for high-performance rendering. SigPro automatically cleans up the `$.watch` instances when nodes are removed.
```javascript
const items = $(["Apple", "Banana", "Cherry"]);
Ul({ class: "list-disc" }, [
ui.For(items, (item) => Li(item), (item) => item)
$.For(items, (item) => Li(item))
]);
```
@@ -103,13 +103,13 @@ Ul({ class: "list-disc" }, [
Since SigPro injects these helpers into the global `window` object, follow these rules to avoid bugs:
1. **Avoid Shadowing**: Don't name your local variables like the tags (e.g., `const Div = ...`). This will "hide" the SigPro helper.
2. **Custom Components**: Always use **PascalCase**, **UPPERCASE**, or **Underscore** prefixes for your own component functions (e.g., `UserCard`, `INPUT`, or `_Input`) to distinguish them from the built-in Tag Helpers and avoid naming collisions.
2. **Custom Components**: Always use **PascalCase** for your own component functions (e.g., `UserCard`, `NavMenu`) to distinguish them from the built-in Tag Helpers and maintain architectural clarity.
:::
---
## 6. Logic to UI Comparison
## 5. Logic to UI Comparison
Here is how a dynamic **User Status** component translates from SigPro logic to the final DOM structure.
Here is how a dynamic **User Status** component translates from SigPro logic to the final DOM structure, handled by the V2 "Saneamiento" engine.
```javascript
// SigPro Component
@@ -121,16 +121,14 @@ const UserStatus = (name, $online) => (
class: 'w-3 h-3 bg-green-500 rounded-full'
}),
P({
// Reactive text content
// Reactive text content via automatic $.watch
class: () => $online() ? "text-bold" : "text-gray-400"
}, name)
])
);
```
| State (`$online`) | Rendered HTML |
| :--- | :--- |
| **`true`** | `<div class="flex..."><span class="w-3..."></span><p class="text-bold">John</p></div>` |
| **`false`** | `<div class="flex..."><span hidden class="w-3..."></span><p class="text-gray-400">John</p></div>` |
| State (`$online`) | Rendered HTML | Memory Management |
| :--- | :--- | :--- |
| **`true`** | `<div class="flex..."><span class="w-3..."></span><p class="text-bold">John</p></div>` | Watcher active |
| **`false`** | `<div class="flex..."><span hidden class="w-3..."></span><p class="text-gray-400">John</p></div>` | Attribute synced |

View File

@@ -1,78 +0,0 @@
# 🖼️ Component Lifecycle: `$.view( )`
The `$.view` function is a specialized wrapper used to manage the lifecycle of a UI component. It tracks all signals, effects, and DOM elements created within it, providing a single point of destruction to prevent memory leaks.
## 🛠 Function Signature
```typescript
$.view(renderFn: Function): RuntimeObject
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`renderFn`** | `Function` | Yes | A function that returns a DOM Node or an array of Nodes. |
**Returns:** A `Runtime` object containing:
* `container`: A `div` (with `display: contents`) holding the rendered content.
* `destroy()`: A function that unmounts the view and cleans up all internal effects/listeners.
---
## 📖 Usage Patterns
### 1. Basic Component Wrapper
When you wrap logic in `$.view`, SigPro creates a "boundary".
```javascript
const myView = $.view(() => {
const count = $(0);
// This effect is "owned" by this view
$.effect(() => console.log(count()));
return Div([
H1("Internal View"),
Button({ onclick: () => count(c => c + 1) }, "Add")
]);
});
// To show it:
document.body.appendChild(myView.container);
// To kill it (removes from DOM and stops all internal effects):
myView.destroy();
```
### 2. Manual Cleanups with `onCleanup`
The `renderFn` receives a helper object that allows you to register custom cleanup logic (like closing a WebSocket or a third-party library instance).
```javascript
const ChartComponent = () => $.view(({ onCleanup }) => {
const socket = new WebSocket("ws://...");
onCleanup(() => {
socket.close();
console.log("Cleanup: WebSocket closed");
});
return Div({ class: "chart-container" });
});
```
---
## 🏗️ Internal Architecture
When `$.view` is called, it performs the following:
1. **Isolation**: It creates a new `Set` of cleanups.
2. **Execution**: It runs your function and captures any `$.effect` or child `$.view` created during execution.
3. **Container**: It wraps the result in a `display: contents` element (which doesn't affect your CSS layout).
4. **Disposal**: When `destroy()` is called, it recursively calls all cleanup functions and removes the container from the DOM.
---
## 💡 Why use `$.view`?
* **Automatic Cleanup**: You don't have to manually stop every effect when a user navigates away.
* **Router Integration**: The SigPro Router (`$.router`) uses `$.view` internally to swap pages and clean up the previous one automatically.
* **Performance**: It ensures that background processes (like intervals or observers) stop as soon as the element is no longer visible.

91
src/docs/api/watch.md Normal file
View File

@@ -0,0 +1,91 @@
# ⚡ Reactivity Control: `$.watch( )`
The `$.watch` function is the reactive engine of SigPro. It allows you to execute code automatically when signals change. In V2, `$.watch` is **polymorphic**: it can track dependencies automatically or follow an explicit list.
## 🛠 Function Signature
```typescript
// Automatic Mode (Magic Tracking)
$.watch(callback: Function): StopFunction
// Explicit Mode (Isolated Dependencies)
$.watch(deps: Signal[], callback: Function): StopFunction
```
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **`target / deps`** | `Function` | `Array` | Yes | Either the code to run (Auto) or an array of signals to watch (Explicit). |
| **`callback`** | `Function` | Only in Explicit | The code that will run when the `deps` change. |
**Returns:** A `StopFunction` that, when called, destroys the watcher and releases memory.
---
## 📖 Usage Patterns
### 1. Automatic Mode (Default)
Any signal you "touch" inside the callback becomes a dependency. SigPro tracks them behind the scenes.
```javascript
const count = $(0);
$.watch(() => {
// Re-runs every time 'count' changes
console.log(`Count is: ${count()}`);
});
```
### 2. Explicit Mode (Advanced Saneamiento) 🚀
This mode **isolates** execution. The callback only triggers when the signals in the array change. Any other signal accessed *inside* the callback will NOT trigger a re-run. This is the "gold standard" for Routers and heavy components.
```javascript
const sPath = $("/home");
const user = $("Admin");
$.watch([sPath], () => {
// Only triggers when 'sPath' changes.
// Changes to 'user' will NOT trigger this, preventing accidental re-renders.
console.log(`Navigating to ${sPath()} as ${user()}`);
});
```
### 3. Automatic Cleanup
If your logic creates timers, event listeners, or other reactive effects, SigPro tracks them as "children" of the current watch. When the watcher re-runs or stops, it kills everything inside automatically.
```javascript
$.watch(() => {
const timer = setInterval(() => console.log("Tick"), 1000);
// Register a manual cleanup if needed
// Or simply rely on SigPro to kill nested $.watch() calls
return () => clearInterval(timer);
});
```
---
## 🛑 Stopping a Watcher
Call the returned function to manually kill the watcher. This is essential for manual DOM injections (like Toasts) or long-lived background processes.
```javascript
const stop = $.watch(() => console.log(count()));
// Later...
stop(); // The link between the signal and this code is physically severed.
```
---
## 💡 Pro Tip: The Microtask Queue
SigPro batches updates. If you update multiple signals in the same execution block, the watcher will only fire **once** at the end of the task.
```javascript
const a = $(0);
const b = $(0);
$.watch(() => console.log(a(), b()));
// This triggers only ONE re-run.
a(1);
b(2);
```

View File

@@ -1,15 +1,25 @@
# 🧩 UI Components `(WIP)`
> **Status: Work In Progress.** > These are high-level, complex visual components designed to speed up development. They often replace native HTML elements with "superpowered" versions that handle their own internal logic, reactivity, and accessibility.
> **Status: Work In Progress.** > These are high-level, complex visual components designed to speed up development. They replace native HTML elements with "superpowered" versions that handle their own internal logic, reactivity, and professional styling.
## ⚠️ Prerequisites
To ensure all components render correctly with their reactive themes and states, your project **must** have the following versions installed:
* **Tailwind CSS v4+**: For the new engine performance and modern CSS variables.
* **DaisyUI v5+**: Required for the updated theme-selectors and improved component classes used in the SigPro UI library.
---
## 1. What are UI Components?
Unlike **Tag Helpers** (which are just functional mirrors of HTML tags), SigPro UI Components are smart abstractions.
Unlike **Tag Helpers** (which are just functional mirrors of HTML tags), SigPro UI Components are smart abstractions:
* **Stateful**: They manage complex internal states (like date ranges, search filtering, or API lifecycles).
* **Reactive**: Attributes prefixed with `$` are automatically tracked.
* **Self-Cleaning**: They automatically use `_cleanups` to destroy observers or event listeners when removed from the DOM.
* **Themed**: Fully compatible with Tailwind CSS and DaisyUI themes.
* **Reactive**: Attributes prefixed with `$` are automatically tracked via `$.watch`.
* **Self-Sane**: They automatically use `._cleanups` to destroy observers or event listeners when removed from the DOM.
* **Themed**: Fully compatible with the DaisyUI v5 theme system and Tailwind v4 utility classes.
---
@@ -17,7 +27,6 @@ Unlike **Tag Helpers** (which are just functional mirrors of HTML tags), SigPro
| Category | Components |
| :--- | :--- |
| **Logic & Flow** | `If`, `For`, `Json` |
| **Forms & Inputs** | `Button`, `Input`, `Select`, `Autocomplete`, `Datepicker`, `Colorpicker`, `CheckBox`, `Radio`, `Range`, `Rating`, `Swap` |
| **Feedback** | `Alert`, `Toast`, `Modal`, `Loading`, `Badge`, `Tooltip`, `Indicator` |
| **Navigation** | `Navbar`, `Menu`, `Drawer`, `Tabs`, `Accordion`, `Dropdown` |
@@ -28,7 +37,7 @@ Unlike **Tag Helpers** (which are just functional mirrors of HTML tags), SigPro
## 3. Examples with "Superpowers"
### A. The Declarative API Flow (`Request` & `Response`)
Instead of manually managing `loading` and `error` flags, use these two together to handle data fetching elegantly.
Instead of manually managing `loading` and `error` flags, use these together to handle data fetching elegantly.
```javascript
// 1. Define the request (it tracks dependencies automatically)
@@ -48,7 +57,7 @@ Div({ class: "p-4" }, [
```
### B. Smart Inputs & Autocomplete
Native inputs are boring. SigPro UI inputs handle labels, icons, password toggles, and validation states out of the box.
SigPro UI inputs handle labels, icons, password toggles, and validation states out of the box using DaisyUI v5 classes.
```javascript
const searchQuery = $("");
@@ -63,7 +72,7 @@ Autocomplete({
```
### C. The Reactive Datepicker
Handles single dates or ranges with a clean, reactive interface.
Handles single dates or ranges with a clean, reactive interface that automatically syncs with your signals.
```javascript
const myDate = $(""); // or { start: "", end: "" } for range
@@ -71,15 +80,15 @@ const myDate = $(""); // or { start: "", end: "" } for range
Datepicker({
label: "Select Expiry Date",
$value: myDate,
range: false // Set to true for range selection
range: false
});
```
### D. Imperative Toasts & Modals
Sometimes you just need to trigger a message without cluttering your template.
Trigger complex UI elements from your logic. These components use `$.mount` internally to ensure they are properly cleaned up from memory after they close.
```javascript
// Show a notification from anywhere in your logic
// Show a notification (Self-destroying after 3s)
Toast("Settings saved successfully!", "alert-success", 3000);
// Control a modal with a simple signal
@@ -104,15 +113,15 @@ The UI library comes with a built-in locale system. It currently supports `es` a
// Set the global UI language
SetLocale("en");
// Access translated strings in your own components
const t = tt("confirm"); // Returns a signal that tracks the current locale
// Access translated strings (Returns a signal that tracks the current locale)
const t = tt("confirm");
```
---
## 5. Best Practices
* **Use `$` for Reactivity**: If a property starts with `$`, it expects a Signal (e.g., `$value: mySignal`).
* **Key your Lists**: When using `For`, always provide a `keyFn` to ensure high-performance DOM reconciliation.
* **Cleanups**: If you build custom components that use `setInterval` or `observers`, add them to the element's `_cleanups` Set.
* **Use `$` for Reactivity**: If a property starts with `$`, the component expects a Signal (e.g., `$value: mySignal`).
* **Automatic Cleaning**: You don't need to manually destroy these components if they are inside a `$.If` or `$.For`. SigPro's core will "sweep" their internal watchers automatically.
* **Manual Cleanups**: If you build custom components using `setInterval` or third-party observers, always add the stop functions to the element's `._cleanups` Set.