Giter Site home page Giter Site logo

rail44 / squark Goto Github PK

View Code? Open in Web Editor NEW
175.0 7.0 3.0 1.47 MB

Rust frontend framework, for web browser and more.

Home Page: https://rail44.github.io/squark/

License: Do What The F*ck You Want To Public License

Rust 100.00%
rust web dom virtual-dom wasm asmjs emscripten frontend-framework wasm-bindgen

squark's Introduction

squark

Rust frontend framework, for web browser and more.

Currently, we depend on nightly channel

Design

  • Separating runtime definition and implemention
    • squark crate has no dependency for specific platform
  • Architecture inspired from Elm and HyperApp
    • Simplicy
    • Elegant
  • Supporting futures-0.1
    • reducer can emit task for async work such as fetch resource

crates

squark

crates.io docs.rs

Core crate.

  • Pure Rust virtual DOM implemention
  • Definition of GUI application
  • Definition of runtime to handle diffirence of virtual DOM

squark-macros

crates.io docs.rs

It provides macro like JSX for helping writing view.
Very thanks to pest parser.

Syntax

view! {
    <button class="some-class" onclick={ |_| Some(Action::Submit) }>
        Button!
    </button>
}

We can generate native Rust expression at compile-time.

squark-web

crates.io docs.rs

Runtime implemention for web browser with usinng wasm-bindgen.

Here is full example of counter app!

#![feature(proc_macro_hygiene)]

extern crate squark;
extern crate squark_macros;
extern crate squark_web;
extern crate wasm_bindgen;
extern crate web_sys;

use squark::{App, Runtime, View, Task};
use squark_macros::view;
use squark_web::WebRuntime;
use wasm_bindgen::prelude::*;
use web_sys::window;

#[derive(Clone, Debug, PartialEq)]
struct State {
    count: isize,
}

impl State {
    pub fn new() -> State {
        State { count: 0 }
    }
}

#[derive(Clone, Debug)]
enum Action {
    ChangeCount(isize),
}

#[derive(Clone, Debug)]
struct CounterApp;
impl App for CounterApp {
    type State = State;
    type Action = Action;

    fn reducer(&self, mut state: State, action: Action) -> (State, Task<Action>) {
        match action {
            Action::ChangeCount(c) => {
                state.count = c;
            }
        };
        (state, Task::empty())
    }

    fn view(&self, state: State) -> View<Action> {
        let count = state.count;
        view! {
            <div>
                { count.to_string() }
                <button onclick={ move |_| Some(Action::ChangeCount(count.clone() + 1)) }>
                    increment
                </button>
                <button onclick={ move |_| Some(Action::ChangeCount(count - 1)) }>
                    decrement
                </button>
            </div>
        }
    }
}

impl Default for CounterApp {
    fn default() -> CounterApp {
        CounterApp
    }
}

#[wasm_bindgen]
pub fn run() {
    WebRuntime::<CounterApp>::new(
        window()
            .unwrap()
            .document()
            .expect("Failed to get document")
            .query_selector("body")
            .unwrap()
            .unwrap(),
        State::new(),
    )
    .run();
}

Project dir is located at examples/counter.

There are some other examples available on examples, most of them use rust-webpack-template.
TodoMVC is working on https://rail44.github.io/squark/.

squark's People

Contributors

dependabot[bot] avatar rail44 avatar renovate-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

squark's Issues

Null returned on `onwheel`

Hello!

I just found this library and it seems really awsome, thank you for the hard work!

Trying to use onwheel in a div but keep getting a Null return value!
I am still super new at bindgen/web-sys/etc, and don't know if this is a mistake on my side or not!

I have edited the with_task example with the view! as follows:

...
       let msg = state.msg;
        view! {
            <div onwheel={ move |v| Some(Action::Debug(format!("Value received is: {:?}", v))) }>    
            { count.to_string()} { msg.to_string() }
          ...
          }

and added the needed code in the the reducer, enum and state;

   Action::Debug(s) => {
          state.msg = s;
   }

Could you tell me if I am missing something?

Kind regards
Calvin

Controlled components not possible

See yewstack/yew#233 (comment) for context.

Essentially, the desired behavior is: if an edit for a field (e.g. an input or text area) is 'rejected' (i.e. not applied to the model), the render should not update. In react this is known as 'controlled components'.

In squark you can test this by applying the patch I've pasted at the bottom and then editing the 'new item' input element on the todomvc example. Because the internal state isn't changing, arguably neither should the render. Unfortunately, it does.

React solves this by restoring state after a change event (described on the linked issue). Note that react also provides uncontrolled components where the value field is not set. I think the important thing is that both options are available (somehow).

diff --git a/examples/todomvc/crate/src/lib.rs b/examples/todomvc/crate/src/lib.rs
index a97c915..f640e85 100644
--- a/examples/todomvc/crate/src/lib.rs
+++ b/examples/todomvc/crate/src/lib.rs
@@ -187,10 +187,10 @@ fn header_view(state: &State) -> View<Action> {
                 class="new-todo"
                 placeholder="What needs to be done?"
                 value={ state.field.clone() }
-                oninput={ |v| match v {
-                    HandlerArg::String(v) => Some(Action::UpdateField(v)),
-                    _ => None,
-                } }
+                //oninput={ |v| match v {
+                //    HandlerArg::String(v) => Some(Action::UpdateField(v)),
+                //    _ => None,
+                //} }
                 onkeydown={ |v| match v {
                     HandlerArg::String(ref v) if v.as_str() == "Enter" => Some(Action::Add),
                     _ => None,

add router?

router maybe importent, when do a real project.

Tag names with dashes are not accepted by the parser

While going thru the increment demo, I tried to add a polymer webcomponent to the page.
The grammar seemed fine with it, but I got the following compilation error (macro panic).

error: proc macro panicked
  --> src/lib.rs:80:9
   |
80 | /         view! {
81 | |             <div>
82 | |                 <iron-icon icon="check"/>
83 | |             </div>
84 | |         }
   | |_________^
   |
   = help: message: called `Result::unwrap()` on an `Err` value: Error { variant: ParsingError { positives: [tag, text], negatives: [] }, location: Pos(8), line_col: Pos((1, 9)), path: None, line: "< div > < iron - icon icon = \"check\" / > < / div >", continued_line: None }

To untrained eyes, it looks like it is trying to separate the tag name using the '-'.

Testing the grammar on pest.rs shows the tokens just fine.

- tag
  - tag_name: "div"
  - attributes: ""
  - children > tag
    - tag_name: "iron-icon"
    - attributes
      - key: "icon"
      - string: "check"
- EOI: ""

Changing the iron-icon tag to ironicon allows the code to compile, but then the tag is wrong.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.