From 308a21726c54c8a0297345a014131246b753cf26 Mon Sep 17 00:00:00 2001 From: kainlite Date: Wed, 23 Mar 2022 20:21:09 -0300 Subject: [PATCH] Fix example and merge --- README.md | 108 ++++++++++++++++------------ examples/form/Cargo.lock | 91 +++++++++++------------ examples/form/Cargo.toml | 10 +-- examples/form/src/lib.rs | 14 +--- yew_form/Cargo.toml | 6 -- yew_form/src/components/checkbox.rs | 15 ---- yew_form/src/components/field.rs | 39 ---------- yew_form/src/form.rs | 8 --- yew_form/src/lib.rs | 10 --- 9 files changed, 111 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index ed38c9e..7d1e69d 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,21 @@ [![License:MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License:Apache](https://img.shields.io/badge/License-Apache-yellow.svg)](https://opensource.org/licenses/Apache-2.0) + # Yew Form + Bringing MVC to Yew! A set of mildly opinionated Yew component to map and validate a model to a HTML form. [Live demo](http://chronogears.com/yew-form/) Supports: -- 2-way Binding to struct (with support for nested structs) -- Validation ([using Keats Validator](https://github.com/Keats/validator)) -- Only `String` and `bool` fields are supported presently. More to come + +- 2-way Binding to struct (with support for nested structs) +- Validation ([using Keats Validator](https://github.com/Keats/validator)) +- Only `String` and `bool` fields are supported presently. More to come ## Usage + Cargo.toml: + ```toml [dependencies] validator = "0.14" @@ -19,7 +24,9 @@ yew = "0.18" yew_form = "0.1" yew_form_derive = "0.1" ``` + main.rs: + ```rust #[macro_use] extern crate validator_derive; @@ -29,7 +36,9 @@ extern crate yew_form_derive; ``` ## Example + Consider the following model: + ```rust #[derive(Model, Validate, PartialEq, Clone)] struct Address { @@ -68,6 +77,7 @@ struct App { ``` For now, the `Form` needs to be instantiated as follows: + ```rust fn create(_props: Self::Properties, link: ComponentLink) -> Self { // Create model initial state @@ -91,28 +101,25 @@ fn create(_props: Self::Properties, link: ComponentLink) -> Self { ``` Fields can then be added to the form as follows: + ```html - - form=&self.form -<<<<<<< HEAD - field_name="first_name" - autocomplete="given-name" -======= - field_name="first_name" ->>>>>>> 0ab668b7f3fb9ba13e1e0d4d97bee619280f3a3d - oninput=self.link.callback(|_: InputData| AppMessage::Update) /> - - - - form=&self.form - field_name="address.street" - class="form-control" - class_invalid="is-invalid red-border" - class_valid="is-valid green-border" - oninput=self.link.callback(|_: InputData| AppMessage::Update) /> -... - field_name="accept_terms" form=&self.form /> + + form=&self.form field_name="first_name" oninput=self.link.callback(|_: + InputData| AppMessage::Update) /> + + + + form=&self.form field_name="address.street" class="form-control" + class_invalid="is-invalid red-border" class_valid="is-valid + green-border" oninput=self.link.callback(|_: InputData| + AppMessage::Update) /> ... + + field_name="accept_terms" form=&self.form /> ``` + The `Field` component takes care of two way binding between `struct Registration` and the HTML `` Validation is done automatically when the user edits the form or programmatically. @@ -124,47 +131,56 @@ if self.form.validate() { ``` Todo/Wish List: -- [ ] Add documentation (In progress) -- [ ] ~~Remove clone requirement from model~~ -- [X] Add `derive` for model to remove need for `vec!` of fields -- [X] Make `oninput` optional -- [ ] Make Yew update the view when `Field` is updated -- [ ] Need to add additional HTML attribute to `Field` -- [X] Remove hard-coded Bootstrap styles -- [X] Add support for additional types such as `i32` -- [ ] Support `Vec` -- [X] Support Rust Stable + +- [ ] Add documentation (In progress) +- [ ] ~~Remove clone requirement from model~~ +- [x] Add `derive` for model to remove need for `vec!` of fields +- [x] Make `oninput` optional +- [ ] Make Yew update the view when `Field` is updated +- [ ] Need to add additional HTML attribute to `Field` +- [x] Remove hard-coded Bootstrap styles +- [x] Add support for additional types such as `i32` +- [ ] Support `Vec` +- [x] Support Rust Stable ## Change Log ### 0.1.8 -- Remove hardcoded Bootstrap css classes -- Fix `examples/form` -- Add `autocomplete` attribute + +- Remove hardcoded Bootstrap css classes +- Fix `examples/form` +- Add `autocomplete` attribute ### 0.1.7 -- Remove `#![feature(get_mut_unchecked)]` from code (Thanks [L0g4n](https://github.com/L0g4n)) + +- Remove `#![feature(get_mut_unchecked)]` from code (Thanks [L0g4n](https://github.com/L0g4n)) ### 0.1.6 -- Removed unsafe code -- Updated yew_form version in documentation + +- Removed unsafe code +- Updated yew_form version in documentation ### 0.1.5 -- Updated to Yew 0.17 + +- Updated to Yew 0.17 ### 0.1.4 -- Added blanket implementation for FieldValue to support `i32`, `bool`, etc... + +- Added blanket implementation for FieldValue to support `i32`, `bool`, etc... ### 0.1.3 + **BREAKING CHANGES** -- Added `#[derive(Model)]` -- No need to manually pass a vector of fields to `Form::new()` + +- Added `#[derive(Model)]` +- No need to manually pass a vector of fields to `Form::new()` ### 0.1.2 -- Added CheckBox + +- Added CheckBox ### 0.1.1 -- Make `Field::oninput` optional +- Make `Field::oninput` optional -(Made with ❤️ with Rust) \ No newline at end of file +(Made with ❤️ with Rust) diff --git a/examples/form/Cargo.lock b/examples/form/Cargo.lock index ccc9a1a..0411c44 100644 --- a/examples/form/Cargo.lock +++ b/examples/form/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "boolinator" @@ -25,15 +25,9 @@ checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" [[package]] name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "cfg-if" -version = "0.1.10" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cfg-if" @@ -43,11 +37,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "console_error_panic_hook" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "wasm-bindgen", ] @@ -125,9 +119,9 @@ dependencies = [ [[package]] name = "gloo-file" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31ba1f51868ae10a0b665c6dccd5ed967486e7c17055d1c889596ee983be493" +checksum = "aa5d6084efa4a2b182ef3a8649cb6506cb4843f22cf907c6e0a799944248ae90" dependencies = [ "gloo-events", "js-sys", @@ -162,20 +156,19 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +checksum = "4d12a7f4e95cfe710f1d624fb1210b7d961a5fb05c4fd942f4feab06e61f590e" dependencies = [ "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] name = "gloo-utils" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d77d28d9a6f7c384d9e40293fa11f05558bf928a993208e12528ee6633cb415" +checksum = "05c77af6f96a4f9e27c8ac23a88407381a31f4a74c3fb985c85aa79b8d898136" dependencies = [ "js-sys", "wasm-bindgen", @@ -207,9 +200,9 @@ checksum = "1f7280c75fb2e2fc47080ec80ccc481376923acb04501957fc38f935c3de5088" [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", @@ -223,9 +216,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.51" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] @@ -238,11 +231,11 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -367,9 +360,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "syn" @@ -384,18 +377,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -503,11 +496,11 @@ checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "wasm-bindgen" -version = "0.2.74" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "serde", "serde_json", "wasm-bindgen-macro", @@ -515,9 +508,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.74" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", @@ -530,11 +523,11 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.24" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -542,9 +535,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.74" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -552,9 +545,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.74" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", "quote", @@ -565,15 +558,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.74" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.51" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/examples/form/Cargo.toml b/examples/form/Cargo.toml index 44b6e0d..adf9f18 100644 --- a/examples/form/Cargo.toml +++ b/examples/form/Cargo.toml @@ -8,11 +8,11 @@ edition = "2018" crate-type = ["cdylib", "rlib"] [dependencies] -lazy_static = "1.4" +lazy_static = "1.4.0" regex = "1" -validator = "0.14" -validator_derive = "0.14" +validator = "0.14.0" +validator_derive = "0.14.0" wasm-bindgen = "0.2" yew = "0.19.3" -yew_form = { version = "0.1", path = "../../yew_form"} -yew_form_derive = { version = "0.1", path = "../../yew_form_derive"} +yew_form = { path = "../../yew_form"} +yew_form_derive = { path = "../../yew_form_derive"} diff --git a/examples/form/src/lib.rs b/examples/form/src/lib.rs index 4a34000..2498bbb 100644 --- a/examples/form/src/lib.rs +++ b/examples/form/src/lib.rs @@ -126,22 +126,12 @@ impl Component for App {
-<<<<<<< HEAD - form={ form } - autocomplete="given_name" -======= - form=form ->>>>>>> 0ab668b7f3fb9ba13e1e0d4d97bee619280f3a3d + form={form} field_name="first_name" class="form-control blue foo bar" class_invalid="is-invalid very-wrong" class_valid="is-valid green" -<<<<<<< HEAD - oninput={ cb.clone() } - /> -======= - oninput=cb.clone() /> ->>>>>>> 0ab668b7f3fb9ba13e1e0d4d97bee619280f3a3d + oninput={cb.clone()} />
{form.field_message("first_name")}
diff --git a/yew_form/Cargo.toml b/yew_form/Cargo.toml index 8924d64..4b6d56d 100644 --- a/yew_form/Cargo.toml +++ b/yew_form/Cargo.toml @@ -10,11 +10,6 @@ readme = "../README.md" categories = [ "web-programming" ] [dependencies] -<<<<<<< HEAD -validator = "0.14.0" -validator_derive = "0.14.0" -yew = "0.18" -======= wasm-bindgen = "0.2" validator = "0.14.0" validator_derive = "0.14.0" @@ -28,4 +23,3 @@ features = [ "HtmlSelectElement", "HtmlTextAreaElement" ] ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b diff --git a/yew_form/src/components/checkbox.rs b/yew_form/src/components/checkbox.rs index c2c5f98..a7e9ef7 100644 --- a/yew_form/src/components/checkbox.rs +++ b/yew_form/src/components/checkbox.rs @@ -1,9 +1,5 @@ use crate::{Form, Model}; -<<<<<<< HEAD -use yew::{html, Callback, Component, ComponentLink, Html, Properties}; -======= use yew::{html, Callback, Component, Context, Html, Properties}; ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b pub enum CheckBoxMessage { OnToggle, @@ -41,15 +37,10 @@ impl Component for CheckBox { type Message = CheckBoxMessage; type Properties = CheckBoxProperties; -<<<<<<< HEAD - fn create(props: Self::Properties, link: ComponentLink) -> Self { - Self { link, props } -======= fn create(ctx: &yew::Context) -> Self { Self { props: ctx.props().clone(), } ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b } fn update(&mut self, ctx: &yew::Context, msg: Self::Message) -> bool { @@ -71,15 +62,9 @@ impl Component for CheckBox { html! { >>>>>> fa67514a4897880b89e3e13161797e6877d3f50b class="form-check-input form-input" /> } diff --git a/yew_form/src/components/field.rs b/yew_form/src/components/field.rs index d006186..d88e4e0 100644 --- a/yew_form/src/components/field.rs +++ b/yew_form/src/components/field.rs @@ -1,27 +1,15 @@ -<<<<<<< HEAD -use yew::{html, Callback, Component, ComponentLink, Html, InputData, Properties, ShouldRender}; -======= use wasm_bindgen::JsCast; use wasm_bindgen::UnwrapThrowExt; use web_sys::Event; use web_sys::HtmlInputElement; use web_sys::InputEvent; -<<<<<<< HEAD:yew_form/src/field.rs -use yew::{html, Callback, Component, Context, Html, Properties}; ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b -======= use yew::{classes, html, Callback, Classes, Component, Context, Html, Properties}; ->>>>>>> 4b9fabffb63393ec7626a4477fd36de12a07fac9:yew_form/src/components/field.rs use crate::form::Form; use crate::Model; pub enum FieldMessage { -<<<<<<< HEAD - OnInput(InputData), -======= OnInput(InputEvent), ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b } fn default_text() -> String { @@ -65,15 +53,7 @@ impl Field { &self.field_name } -<<<<<<< HEAD:yew_form/src/field.rs -<<<<<<< HEAD - pub fn class(&self) -> &'static str { -======= - pub fn class(&self) -> String { ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b -======= pub fn class(&self) -> Classes { ->>>>>>> 4b9fabffb63393ec7626a4477fd36de12a07fac9:yew_form/src/components/field.rs let s = self.form.state(); let field = s.field(&self.field_name); @@ -153,24 +133,6 @@ impl Component for Field { fn view(&self, ctx: &Context) -> Html { html! { >>>>>> fa67514a4897880b89e3e13161797e6877d3f50b -======= class={self.class().to_string()} id={self.field_name.clone()} type={self.input_type.clone()} @@ -179,7 +141,6 @@ impl Component for Field { value={self.form.field_value(&self.field_name)} oninput={ctx.link().callback(FieldMessage::OnInput )} disabled={ctx.props().disabled.unwrap_or_default()} ->>>>>>> 4b9fabffb63393ec7626a4477fd36de12a07fac9:yew_form/src/components/field.rs /> } } diff --git a/yew_form/src/form.rs b/yew_form/src/form.rs index 5a5c105..a4d9e4e 100644 --- a/yew_form/src/form.rs +++ b/yew_form/src/form.rs @@ -1,9 +1,6 @@ use std::cell::{Ref, RefCell, RefMut}; use std::rc::Rc; -<<<<<<< HEAD -======= use yew::html::ImplicitClone; ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b use crate::form_state::FormState; use crate::Model; @@ -62,12 +59,7 @@ impl Form { impl PartialEq for Form { fn eq(&self, other: &Self) -> bool { -<<<<<<< HEAD - Rc::ptr_eq(&self.state, &other.state) - || self.state.borrow().model == other.state.borrow().model -======= Rc::ptr_eq(&self.state, &other.state) || self.state().model == other.state().model ->>>>>>> fa67514a4897880b89e3e13161797e6877d3f50b } fn ne(&self, other: &Self) -> bool { diff --git a/yew_form/src/lib.rs b/yew_form/src/lib.rs index 2f3fef7..907165a 100644 --- a/yew_form/src/lib.rs +++ b/yew_form/src/lib.rs @@ -1,14 +1,4 @@ -<<<<<<< HEAD -pub use checkbox::CheckBox; -pub use field::Field; -pub use form::Form; -pub use model::{split_field_path, Model}; - -pub mod checkbox; -pub mod field; -======= pub mod components; ->>>>>>> 4b9fabffb63393ec7626a4477fd36de12a07fac9 pub mod form; pub mod form_field; pub mod form_state;