consecuit 0.2.0

A functional web UI framework that uses the type system for hooks and more
Documentation
# Consecuit

[<img alt="crates.io" src="https://img.shields.io/crates/v/consecuit?style=for-the-badge" height="20">](https://crates.io/crates/consecuit)
[<img alt="crates.io" src="https://img.shields.io/docsrs/consecuit?style=for-the-badge" height="20">](https://docs.rs/consecuit)

An **experimental** functional web UI framework that uses the Rust type system for hooks and more.

## How is this different from other frameworks?

**Other Functional UI Frameworks**:

* Require the developer to follow the [Rule of Hooks]https://reactjs.org/docs/hooks-rules.html or something similar.
* Dynamically identify components/hooks and maintain their states by counting the order in which they are called.
* Dynamic design:

	* Components are dynamically created and mounted as their parents render.
	* Components may be mounted or unmounted depending on state.

**Consecuit**:

* Automatically enforce the Rule of Hooks using the Rust type system.
* Statically know every component that will be created and every hook call that will happen.
* Static-first design:

	* Components are statically mounted at the start of the app and remain mounted forever by default.
	* Mounting/unmounting based on state are considered special cases available through explicitly using `opt_comp`, `vec_comps`, etc.

## What does it look like?
Take a look at our
[TodoMVC](https://wishawa.github.io/consecuit/todomvc)
(and see [its source code](https://github.com/wishawa/consecuit/tree/main/examples/todomvc)).

Or if you want something simpler, here is the code for a counter.

```rust
use consecuit::prelude::*;
use consecuit_html::prelude::*;
use wasm_bindgen::prelude::*;

#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
    consecuit::mount::mount_app(counter);
    Ok(())
}

fn counter(cc: ComponentBuilder, _: ()) -> impl ComponentReturn {
    let (cc, (count, setter)) = cc.hook(use_state, 0);

	let setter1 = setter.clone();
    let decrement = Callback::new(move |_ev| {
        setter1.update_with(|v| v - 1);
    });

    let increment = Callback::new(move |_ev| {
        setter.update_with(|v| v + 1);
    });
    
    cc_tree!(
		<button {html_props().onclick(decrement)}>"-"</button>
		{count.to_string()}
		<button {html_props().onclick(increment)}>"+"</button>
    )
}
```

There are more counter examples [here](https://github.com/wishawa/consecuit/tree/main/examples/counters/src/lib.rs)
(with live demo [here](https://wishawa.github.io/consecuit/counters/)),
including one without macro and one with logic extracted into a `use_counter` function.

## How do I start?

Follow our simple guide below:
<details>
<summary>Click to expand guide</summary>

Note: This guide is for you to get started as quickly as possible.
The WASM setup part of the guide is very basic.
You should read the [rustwasm book](https://rustwasm.github.io/wasm-bindgen/introduction.html) later on.

1. Initialize a new lib crate.

    ```shell
    cargo new --lib YOUR_CRATE_NAME_HERE
    cd YOUR_CRATE_NAME_HERE
    ```

1. Add this to your `Cargo.toml`:

    ```
    [lib]
    crate-type = ["cdylib"]

    [dependencies]
    wasm-bindgen = "0.2.74"
    consecuit = "0.2.0"
    consecuit_html = "0.2.0"
    ```

1. Create an `index.html` in the root of your project with this content.

    ```html
    <html>
    <head>
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
    </head>
    <body>
        <script type="module">
            import init from './pkg/YOUR_CRATE_NAME_HERE.js';
            init();
        </script>
    </body>
    </html>
    ```

    (replace `YOUR_CRATE_NAME_HERE` with the name of your crate.)

1. Install `wasm-pack`:

    ```shell
    cargo install wasm-pack
    ```

1. Write your code.
    
    You can copy-paste the [counters example above]https://github.com/wishawa/consecuit#what-does-it-look-like.
            
    Also take a look at [the examples directory]https://github.com/wishawa/consecuit/tree/main/examples/ and [the docs]https://docs.rs/consecuit.

1. Build it!

    ```shell
    wasm-pack build --dev --target web
    ```

1. Serve it!

    ```shell
    # Install a simple web server.
    cargo install microserver
    # And run it!
    microserver
    ```

Final code is in [examples/minimal_counter](https://github.com/wishawa/consecuit/tree/main/examples/minimal_counter).
</details>

[The docs](https://docs.rs/consecuit) have more info on creating components and hooks.

## What's next?

This library is still in an early stage. A lot of features are missing.
(For example, inline styling is not available right now; you need to use class names and write CSS.)

Contributions are welcomed!

**This crate uses unsafe.**

All publicly exposed functions are safe.