Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/schell/mogwai
The minimalist, obvious, graphical, web application interface
https://github.com/schell/mogwai
dom frontend html mogwai reactive rust ui web
Last synced: about 8 hours ago
JSON representation
The minimalist, obvious, graphical, web application interface
- Host: GitHub
- URL: https://github.com/schell/mogwai
- Owner: schell
- Created: 2019-11-10T18:27:51.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2024-11-08T02:10:59.000Z (about 2 months ago)
- Last Synced: 2024-12-16T01:00:17.509Z (7 days ago)
- Topics: dom, frontend, html, mogwai, reactive, rust, ui, web
- Language: Rust
- Homepage:
- Size: 6.84 MB
- Stars: 430
- Watchers: 15
- Forks: 26
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
mogwai
> **m**inimal, **o**bvious, **g**raphical **w**eb **a**pplication **i**nterface
[![Crates.io][ci]][cl]
[ci]: https://img.shields.io/crates/v/mogwai.svg
[cl]: https://crates.io/crates/mogwai/`mogwai` is a view library for creating GUI applications.
It is written in Rust and runs in your browser and has enough functionality server-side
to do rendering. It is an alternative to React, Backbone, Ember, Elm, Purescript, etc.- [goals](#goals)
- [concepts](#concepts)
- [example](#example)
- [intro](#introduction)
- [why](#why)
- [beginning](#ok---where-do-i-start)
- [cookbook](#cookbook)
- [more examples](#more-examples)
- [sponsor this project](#sponsorship)## goals
* provide a declarative approach to creating and managing view nodes
* encapsulate component state and compose components easily
* explicate view mutation
* be small and fast (aka keep it snappy)## concepts
The main concepts behind `mogwai` are* **sinks and streams instead of callbacks**
View events like click, mouseover, etc are sent through streams instead of invoking a callback.
Streams can be mapped, filtered and folded.* **widget views are dumb**
A view is just a struct that mutates the UI tree after receiving a message from a stream.
Views are constructed and nested using plain Rust functions or an RSX macro.* **widget logic is one or more async tasks that loop over event messages**
Widgets use asynchronous task loops that receive events from the view and send updates
to the view in response.## example
Here is an example of a button that counts the number of times it has been clicked:```rust, no_run
use mogwai_dom::prelude::*;#[derive(Default)]
struct Button {
clicks: usize,
click: Output<()>,
text: Input,
}impl Button {
/// Convert into a `ViewBuilder`
fn builder(mut self) -> ViewBuilder {
rsx! (
button(on:click=self.click.sink().contra_map(|_: JsDomEvent| ())) {
// Using braces we can embed rust values in our UI tree.
// Here we're creating a text node that starts with the
// string "Clicked 0 times" which updates every time a
// message is received on the stream.
{("Clicked 0 times", self.text.stream().unwrap())}
}
).with_task(async move {
while let Some(()) = self.click.get().await {
self.clicks += 1;
self.text.set(if self.clicks == 1 {
"Clicked 1 time".to_string()
} else {
format!("Clicked {} times", self.clicks)
}).await.unwrap();
}
})
}
}let btn = Button::default();
// Get a sink to manually send events.
let mut click_sink = btn.click.sink();
// Build the view to render in the browser
let view = Dom::try_from(btn.builder()).unwrap();
// Attach it to the browser's DOM tree
view.run().unwrap();// Spawn asyncronous updates
wasm_bindgen_futures::spawn_local(async move {
// Queue some messages for the view as if the button had been clicked:
click_sink.send(()).await.unwrap();
click_sink.send(()).await.unwrap();
// view's html is now "Clicked 2 times"
});
```## introduction
If you're interested in learning more - please read the [introduction and
documentation](https://docs.rs/mogwai-dom/0.1.0/mogwai_dom/an_introduction/index.html).## why
* No vdom diffing keeps updates snappy and the implementation minimal
* Async logic by default
* Explicit mutation
* `ViewBuilder` allows running on multiple platforms (web, ios, android, desktop, etc)`mogwai` uses streams, sinks, a declarative view builder and async
logic to define components and how they change over time.View mutation is explicit and happens as a result of views receiving messages, so there
is no performance overhead from vdom diffing.If you prefer a functional style of programming with lots of maps and folds -
or if you're looking to go _vroom!_ then maybe `mogwai` is right for you :)Please do keep in mind that `mogwai` is still in alpha and the API is actively
changing - PRs, issues and questions are welcomed. As of the `0.6` release we
expect that the API will be relatively backwards compatible.### made for rustaceans, by a rustacean
`mogwai` is a Rust first library. There is no requirement that you have `npm` or
`node`. Getting your project up and running without writing any javascript is easy
enough.### benchmarketing
`mogwai` is snappy! Here are some very handwavey and sketchy todomvc metrics:![mogwai performance benchmarking](img/perf.png)
## ok - where do i start?
First you'll need new(ish) version of the rust toolchain. For that you can visit
https://rustup.rs/ and follow the installation instructions.Then you'll need [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/).
For starting a new mogwai project we'll use the wonderful `cargo-generate`, which
can be installed using `cargo install cargo-generate`.Then run
```shell
cargo generate --git https://github.com/schell/mogwai-template.git
```
and give the command line a project name. Then `cd` into your sparkling new
project and
```shell
wasm-pack build --target web
```
Then, if you don't already have it, `cargo install basic-http-server` or use your
favorite alternative to serve your app:
```shell
basic-http-server -a 127.0.0.1:8888
```
Happy hacking! :coffee: :coffee: :coffee:## cookbook
:green_book: [Cooking with Mogwai](https://zyghost.com/guides/mogwai-cookbook/index.html) is a series
of example solutions to various UI problems. It aims to be a good reference doc but not a step-by-step tutorial.## group channel :phone:
Hang out and talk about `mogwai` in the support channel:* [direct link to element app](https://app.element.io/#/room/#mogwai:matrix.org)
* invitation https://matrix.to/#/!iABugogSTxJNzlrcMW:matrix.org?via=matrix.org.## more examples please
Examples can be found in [the examples folder](https://github.com/schell/mogwai/blob/master/examples/).To build the examples use:
```shell
wasm-pack build --target web examples/{the example}
```Additional external examples include:
- [mogwai-realworld](https://github.com/schell/mogwai-realworld/) A "real world" app implementation (WIP)
- [the benchmark suite](https://github.com/schell/todo-mvc-bench/)
- your example here ;)## sponsorship
Please consider sponsoring the development of this library!* [sponsor me on github](https://github.com/sponsors/schell/)