neoview 0.0.4

a reactive, lightweight and safe declarative UI framework
Documentation
# NeoView
NeoView is a lightweight, modern declarative UI framework that prioritizes robustness, safety, and efficiency over complex runtime magic.

Aligned with Rust's core principles, NeoView offers a practical middle ground in declarative UI design. It supports ergonomic, fully reactive UI definitions with a strong emphasis on safety, robustness, efficiency, and renderer agnosticism.

This crate provides the core components used by all renderers. For more information about a specific renderer, see its respective crate.

# Reactive System
Inspired by SolidJS and Leptos, NeoView is powered by fine-grained reactivity. However, instead of relying on anonymous signals that carry heavy overhead, it utilizes a context-passing approach that satisfies the borrow checker while ensuring clear ownership and minimal overhead.

Reactive states (also called properties) are stored in [`Store`]. These states are created by [`prop`](Store::prop) and accessed by ID ([`PropId`]) through methods like [`read`](Store::read), [`write`](Store::write), [`get`](Store::get), and [`update`](Store::update) on the [`Store`].
```rust
let ctx = /* some `Context` */
let nb = ctx.prop(1);
assert_eq!(ctx.get(nb), 1);
ctx.write(nb, 2);
assert_eq!(ctx.get(nb), 2);
```

Reactive logic can be placed inside [`effect`s](Store::effect), and derived properties are created via [`computed`](Store::computed).
```rust
let nb = ctx.prop(1);
ctx.effect(move |ctx| println!("nb: {}", ctx.get(nb)));
ctx.write(nb, 2); // => nb: 2
```

Any place that accesses state requires mutable access to a [`Context`], which is the type that owns the [`Store`], the UI, and everything related to it.

[`Context`] and any type that provides access to the [`Store`] implement [`StoreProv`]ider, exposing the common methods of the [`Store`] directly.

# Templating
NeoView utilizes a templating approach called chunked templating. The UI is constructed from multiple interleaved chunks, each chunk contains its own inlined logic and can host nested subchunks. This enables localized, nested UIs without requiring an excessive number of micro-components.

The [`chunk`] macro allows writing UIs in a simple, expressive, object-like syntax.
```rust
// using neoview-web
chunk!(build, div {
	h1 { "counter" }
	do {
		let count = build.prop(0);
		chunk!(build, button(
			on.click: (move |ctx, _| ctx.update(count, |v| *v += 1))
		) { "count: ", count });
	}
});
```

The UI is constructed at init time in an imperative style, and updates flow directly to specific elements using fine-grained reactivity.

All Rust control flow and even all imperative patterns can be used inside chunks. There is no custom syntax for components, they are simply functions that borrow the context.

```rust
fn counter(build: &mut ChunkBuild, name: PropId<String>) {
	let count = build.prop(0);
	chunk!(build, button(
		on.click: (move |ctx, _| ctx.update(count, |v| *v += 1))
	) { name, ": ", count });
}
fn main() {
	// ...
	chunk!(build, div {
		for name in 'a'..'z' {
			let name = build.prop(name.to_string());
			counter(build, name);
		}
	})
}
```

Note that the structure generated by these chunks is static rather than dynamic.

# Renderers
NeoView is renderer-agnostic, it supports any platform or renderer, provided they implement the necessary items.

It provides only the sharable parts between the renderers (the reactivity system and the chunk language) and also the philosophy, the unique rest is lift to the renderer.

The available renderers include:
- [`neoview-web`]https://docs.rs/neoview-web/latest/neoview-web/: A renderer targeting the web platform based on HTML and the DOM.