wip: more work on updating syntad

This commit is contained in:
Jonathan Kelley committed 2021-06-15 10:02:46 -04:00
1 parent e45b6e0aa2
commit 47e896038e
27 files changed
+376 -142

No files matched your search

+3 -2
View File
@@ -6,9 +6,10 @@ members = [
"packages/web", "packages/web",
"packages/dioxus", "packages/dioxus",
"packages/ssr", "packages/ssr",
"packages/docsite",
"packages/recoil",
"packages/router",
] ]
# "packages/recoil",
# "packages/docsite",
# "packages/webview", # "packages/webview",
# "packages/cli", # "packages/cli",
+2 -2
View File
@@ -8,7 +8,7 @@
Dioxus is a portable, performant, and ergonomic framework for building cross-platform user experiences in Rust. Dioxus is a portable, performant, and ergonomic framework for building cross-platform user experiences in Rust.
```rust ```rust
fn Example(ctx: Context<()>) -> VNodes { fn Example(ctx: Context<()>) -> VNode {
let (selection, set_selection) = use_state(&ctx, || "..?"); let (selection, set_selection) = use_state(&ctx, || "..?");
ctx.render(rsx! { ctx.render(rsx! {
@@ -41,7 +41,7 @@ If you know React, then you already know Dioxus.
<th><a href="http://github.com/jkelleyrtp/dioxus">Web</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">Web</a></th>
<th><a href="http://github.com/jkelleyrtp/dioxus">Desktop</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">Desktop</a></th>
<th><a href="http://github.com/jkelleyrtp/dioxus">Mobile</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">Mobile</a></th>
<th><a href="http://github.com/jkelleyrtp/dioxus">State Management</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">State</a></th>
<th><a href="http://github.com/jkelleyrtp/dioxus">Docs</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">Docs</a></th>
<th><a href="http://github.com/jkelleyrtp/dioxus">Tools</a></th> <th><a href="http://github.com/jkelleyrtp/dioxus">Tools</a></th>
<tr> <tr>
File renamed without changes.
+12
View File
@@ -314,6 +314,10 @@ impl VirtualDom {
Ok(()) Ok(())
} }
pub fn base_scope(&self) -> &Scope {
todo!()
}
} }
// TODO! // TODO!
@@ -802,6 +806,14 @@ Any function prefixed with "use" should not be called conditionally.
|_| {}, |_| {},
) )
} }
fn suspend<O>(
&self,
f: impl Future<Output = O>,
g: impl FnOnce(O) -> VNode<'src> + 'src,
) -> VNode<'src> {
todo!()
}
} }
// ================================================================================== // ==================================================================================
+17
View File
@@ -0,0 +1,17 @@
<svg
x="0px"
y="0px"
viewBox="0 0 100 100"
width="15"
height="15"
class="css-83uoqv"
>
<path
fill="currentColor"
d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0, 0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
></path>
<polygon
fill="currentColor"
points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
></polygon>
</svg>

After

Width:  |  Height:  |  Size: 427 B

+9
View File
@@ -0,0 +1,9 @@
use dioxus_ssr::prelude::*;
pub static Blog: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
};
@@ -0,0 +1,9 @@
use dioxus_ssr::prelude::*;
pub static Community: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
};
+9
View File
@@ -0,0 +1,9 @@
use dioxus_ssr::prelude::*;
pub static Docs: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
};
@@ -0,0 +1,42 @@
use dioxus_ssr::prelude::*;
const HeroContent: [(&'static str, &'static str); 3] = [
("Declarative",
"React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.\nDeclarative views make your code more predictable and easier to debug."),
("Component-Based", "Build encapsulated components that manage their own state, then compose them to make complex UIs.\nSince component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM."),
("Learn Once, Write Anywhere", "We don’t make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code.\nReact can also render on the server using Node and power mobile apps using React Native."),
];
const SnippetHighlights: &'static str = include_str!("./../snippets.md");
pub static Home: FC<()> = |ctx| {
let hero = HeroContent.iter().map(|(title, body)| {
rsx! {
div {
h3 { "{title}" }
div { {body.split("\n").map(|paragraph| rsx!( p{"{paragraph}"} ))} }
}
}
});
let snippets: Vec<VNode> = crate::utils::markdown_to_snippet(ctx, SnippetHighlights);
rsx! { in ctx,
div {
header {
// Hero
section {
div { {hero} }
}
hr {}
// Highlighted Snippets
section {
{snippets}
}
}
div {}
section {}
}
}
};
@@ -0,0 +1,9 @@
use dioxus_ssr::prelude::*;
pub static Tutorial: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
};
+127 -72
View File
@@ -1,97 +1,152 @@
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
use dioxus_ssr::{ use dioxus_ssr::{prelude::*, TextRenderer};
prelude::*, pub mod utils;
prelude::{builder::IntoVNode, dioxus::events::on::MouseEvent}, mod components {
TextRenderer, mod community;
}; pub use community::*;
mod utils; mod docs;
pub use docs::*;
mod blog;
pub use blog::*;
mod homepage;
pub use homepage::*;
mod tutorial;
pub use tutorial::*;
}
use components::*;
fn main() { fn main() {
let renderer = TextRenderer::new(App); let renderer = TextRenderer::new(App);
/*
renderer.render_at("community")
*/
} }
static App: FC<()> = |ctx| { static App: FC<()> = |ctx| {
rsx! { in ctx, let (url, set_url) = use_state(&ctx, || "");
let body = match *url {
"community" => rsx!(in ctx, Community {}),
"tutorial" => rsx!(in ctx, Tutorial {}),
"blog" => rsx!(in ctx, Blog {}),
"docs" => rsx!(in ctx, Docs {}),
_ => rsx!(in ctx, Home {}),
};
ctx.render(rsx! {
div { div {
Home {} NavBar {}
Docs {} {body}
Tutorial {} Footer {}
Blog {}
Community {}
} }
} })
}; };
const HeroContent: [(&'static str, &'static str); 3] = [ static NavBar: FC<()> = |ctx| {
("Declarative", ctx.render(rsx! {
"React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.\nDeclarative views make your code more predictable and easier to debug."), header {
a {
href: "/"
img { /*logo*/ }
span {}
}
nav {
a { href: "/community/support", "Community" }
a { href: "/docs/getting-started", "Docs" }
a { href: "/tutorial/tutorial", "Tutorial" }
a { href: "/blog/", "Blog" }
}
form {}
div {}
}
})
};
("Component-Based", "Build encapsulated components that manage their own state, then compose them to make complex UIs.\nSince component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM."), static SECTIONS: &[(&str, &[(&str, &str)])] = &[
(
("Learn Once, Write Anywhere", "We don’t make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code.\nReact can also render on the server using Node and power mobile apps using React Native."), "Docs",
&[
("Installation", "docs/installation"),
("Main Concepts", "docs/main"),
("Advanced Guides", "docs/advanced"),
("Hooks", "docs/hooks"),
("Testing", "docs/testing"),
("Contributing", "docs/contributing"),
("FAQ", "docs/faq"),
],
),
(
"Channels",
&[("Github", "https://github.com/jkelleyrtp/dioxus")],
),
(
"Community",
&[
("Code of Conduct", "docs/installation"),
("Community Resources", "docs/main"),
],
),
(
"More",
&[
("Tutorial", "docs/installation"),
("Blog", "docs/main"),
("Privacy", "docs/advanced"),
("Terms", "docs/hooks"),
],
),
]; ];
const SnippetHighlights: &'static str = include_str!("./snippets.md"); fn Footer(ctx: Context<()>) -> VNode {
let sections = SECTIONS.iter().map(|(section, raw_links)| {
static Home: FC<()> = |ctx| { let links = raw_links.iter().map(|(link_name, href)| {
let hero = HeroContent.iter().map(|(title, body)| { rsx! (
a { href: "{href}",
"{link_name}",
{href.starts_with("http").then(|| rsx!( ExternalLinkIcon {} ))}
}
)
});
rsx! { rsx! {
div { div {
h3 { "{title}" } div { "{section}" }
div { {body.split("\n").map(|paragraph| rsx!( p{"{paragraph}"} ))} } {links}
} }
} }
}); });
let snippets: Vec<VNode> = utils::markdown_to_snippet(ctx, SnippetHighlights);
rsx! { in ctx, ctx.render(rsx! {
div { footer {
header { div {
// Hero div {
section { div {
div { {hero} } {sections}
} }
hr {} section {
// Highlighted Snippets a {
section { img {}
{snippets} }
p {}
}
} }
} }
div {}
section {}
} }
} })
}; }
static Docs: FC<()> = |ctx| { const ExternalLinkIcon: FC<()> = |ctx| {
rsx! { in ctx, ctx.render(html! {
div { <svg x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15">
<path
} fill="currentColor"
} d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0, 0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
}; ></path>
<polygon
static Tutorial: FC<()> = |ctx| { fill="currentColor"
rsx! { in ctx, points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
div { ></polygon>
</svg>
} })
}
};
static Blog: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
};
static Community: FC<()> = |ctx| {
rsx! { in ctx,
div {
}
}
}; };
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"rust-analyzer.inlayHints.enable": true "rust-analyzer.inlayHints.enable": false
} }
+1
View File
@@ -12,6 +12,7 @@ dioxus-core = { path = "../core" }
thiserror = "1.0.24" thiserror = "1.0.24"
log = "0.4.14" log = "0.4.14"
im-rc = "15.0.0" im-rc = "15.0.0"
futures = "0.3.15"
[dev-dependencies] [dev-dependencies]
uuid = { version = "0.8.2", features = ["v4", "wasm-bindgen"] } uuid = { version = "0.8.2", features = ["v4", "wasm-bindgen"] }
+3 -3
View File
@@ -29,9 +29,9 @@ impl TitleController {
fn main() { fn main() {
wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(|ctx| { wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(|ctx| {
let title = use_read(ctx, &TITLE); let title = use_read(&ctx, &TITLE);
let subtitle = use_read(ctx, &SUBTITLE); let subtitle = use_read(&ctx, &SUBTITLE);
let controller = use_recoil_api(ctx, TitleController::new); let controller = TitleController::new(use_recoil_api(&ctx));
rsx! { in ctx, rsx! { in ctx,
div { div {
+1 -1
View File
@@ -21,7 +21,7 @@ fn update_title(api: &RecoilApi) {
static App: FC<()> = |ctx| { static App: FC<()> = |ctx| {
let title = use_read(&ctx, &TITLE); let title = use_read(&ctx, &TITLE);
let next_light = use_recoil_api(ctx, |api| move |_| update_title(&api)); let next_light = use_recoil_api(&ctx, |api| move |_| update_title(&api));
rsx! { in ctx, rsx! { in ctx,
div { div {
+1 -1
View File
@@ -14,7 +14,7 @@ struct Todo {
static App: FC<()> = |ctx| { static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {}); use_init_recoil_root(ctx, |_| {});
let todos = use_read(ctx, &TODOS); let todos = use_read(&ctx, &TODOS);
rsx! { in ctx, rsx! { in ctx,
div { div {
+1 -1
View File
@@ -6,7 +6,7 @@ const COUNT: Atom<i32> = |_| 0;
static App: FC<()> = |ctx| { static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {}); use_init_recoil_root(ctx, |_| {});
let (count, set_count) = use_read_write(ctx, &COUNT); let (count, set_count) = use_read_write(&ctx, &COUNT);
rsx! { in ctx, rsx! { in ctx,
div { div {
+3 -3
View File
@@ -17,12 +17,12 @@ static App: FC<()> = |ctx| {
}; };
static Banner: FC<()> = |ctx| { static Banner: FC<()> = |ctx| {
let count = use_read(ctx, &C); let count = use_read(&ctx, &C);
ctx.render(rsx! { h1 { "Count: {count}" } }) ctx.render(rsx! { h1 { "Count: {count}" } })
}; };
static BtnA: FC<()> = |ctx| { static BtnA: FC<()> = |ctx| {
let (a, set) = use_read_write(ctx, &A); let (a, set) = use_read_write(&ctx, &A);
rsx! { in ctx, rsx! { in ctx,
div { "a" div { "a"
button { "+", onclick: move |_| set(a + 1) } button { "+", onclick: move |_| set(a + 1) }
@@ -32,7 +32,7 @@ static BtnA: FC<()> = |ctx| {
}; };
static BtnB: FC<()> = |ctx| { static BtnB: FC<()> = |ctx| {
let (b, set) = use_read_write(ctx, &B); let (b, set) = use_read_write(&ctx, &B);
rsx! { in ctx, rsx! { in ctx,
div { "b" div { "b"
button { "+", onclick: move |_| set(b + 1) } button { "+", onclick: move |_| set(b + 1) }
@@ -0,0 +1,50 @@
// const Posts: AtomFamily = |family| {
// family.on_get(|key| {
// //
// })
// };
fn main() {
wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(App))
}
use std::future::Future;
use dioxus_core::prelude::*;
static App: FC<()> = |ctx| {
//
let title = use_async_atom();
let title_card = suspend(&ctx, title, move |val| {
//
rsx!(in ctx, div {
h3 { "{val}" }
})
});
// let fut = (use_async_atom(), use_async_atom());
// let title_card2 = ctx.suspend(fut, move |(text, text2)| {
// ctx.render(rsx!( h3 { "{text}" } ))
// });
ctx.render(rsx! {
div {
{title_card}
// {title_card2}
}
})
};
async fn use_async_atom() -> String {
todo!()
}
fn suspend<'a, O>(
c: &impl Scoped<'a>,
f: impl Future<Output = O>,
g: impl FnOnce(O) -> VNode<'a> + 'a,
) -> VNode<'a> {
todo!()
}
+2
View File
@@ -525,6 +525,8 @@ mod utils {
use super::*; use super::*;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
pub struct RecoilApi {}
/// This tiny util wraps your main component with the initializer for the recoil root. /// This tiny util wraps your main component with the initializer for the recoil root.
/// This is useful for small programs and the examples in this crate /// This is useful for small programs and the examples in this crate
pub fn RecoilApp<T: 'static>( pub fn RecoilApp<T: 'static>(
+17 -22
View File
@@ -4,7 +4,7 @@ Dioxus-router provides a use_router hook that returns a different value dependin
The router is generic over any value, however it makes sense to return a different set of VNodes The router is generic over any value, however it makes sense to return a different set of VNodes
and feed them into the App's return VNodes. and feed them into the App's return VNodes.
Using the router should feel similar to tide's routing framework where an "address" book is assembled at the head. Using the router should feel similar to tide's routing framework where an "address" book is assembled at the head of the app.
Here's an example of how to use the router hook: Here's an example of how to use the router hook:
@@ -13,32 +13,27 @@ static App: FC<()> = |ctx| {
// Route returns the associated VNodes // Route returns the associated VNodes
// This hook re-fires when the route changes // This hook re-fires when the route changes
let route = use_router(ctx, |cfg| { let route = use_router(ctx, |router| {
cfg.at("/").serve(|ctx| { router.at("/").get(|path| {
html!{ <LandingPage /> } rsx!{ <LandingPage /> }
}); });
router.at("/shoes/:id").get(|path| {
cfg.at("/shoes/:id").serve(|ctx| { let id: Uuid = path.parse().unwrap();
let id: Uuid = ctx.ctx.parse().unwrap(); rsx!{ <ShoesPage id=id /> }
html!{ <ShoesPage id=id /> }
}); });
router.at("/pants/:id").get(|path| {
cfg.at("/pants/:id").serve(|ctx| { let id: Uuid = path.parse().unwrap();
let id: Uuid = ctx.ctx.parse().unwrap(); rsx!{ <PantsPage id=id /> }
html!{ <PantsPage id=id /> }
}); });
}); });
html! { ctx.render(rsx!{
<PanicBoundary model={|_| html!{<div>"Uh oh!"</div>}}> div {
<StateManager> Navbar {}
<ThemeSystem> {route}
<Header /> Footer {}
{route} }
</ThemeSystem> })
</StateManager>
</PanicBoundary >
}
}; };
``` ```
+5 -3
View File
@@ -34,10 +34,11 @@ fn html_render(
write!(f, "\n</{}>", el.tag_name)?; write!(f, "\n</{}>", el.tag_name)?;
Ok(()) Ok(())
} }
VNode::Text(t) => write!(f, "{}", t.text), VNode::Text(text) => write!(f, "{}", text),
VNode::Suspended => todo!(), VNode::Suspended => todo!(),
VNode::Component(vcomp) => { VNode::Component(vcomp) => {
let id = vcomp.ass_scope.as_ref().borrow().unwrap(); let id = vcomp.ass_scope.borrow().unwrap();
// let id = vcomp.ass_scope.as_ref().borrow().unwrap();
let new_node = dom let new_node = dom
.components .components
.try_get(id) .try_get(id)
@@ -46,6 +47,7 @@ fn html_render(
.current_head_node(); .current_head_node();
html_render(&dom, new_node, f) html_render(&dom, new_node, f)
} }
VNode::Fragment(_) => todo!(),
} }
} }
@@ -61,7 +63,7 @@ fn test_serialize() {
{(0..20).map(|f| rsx!{ {(0..20).map(|f| rsx!{
div { div {
title: "About W3Schools" title: "About W3Schools"
style: "color:blue;text-align:center" // style: "color:blue;text-align:center"
class: "About W3Schools" class: "About W3Schools"
p { p {
title: "About W3Schools" title: "About W3Schools"
+8 -1
View File
@@ -28,6 +28,7 @@ recoil = { path = "../recoil" }
# html-validation = { path = "../html-validation", version = "0.1.1" } # html-validation = { path = "../html-validation", version = "0.1.1" }
async-channel = "1.6.1" async-channel = "1.6.1"
wee_alloc = "0.4.5"
# futures-lite = "1.11.3" # futures-lite = "1.11.3"
[dependencies.web-sys] [dependencies.web-sys]
@@ -62,7 +63,13 @@ features = [
] ]
[profile.release] [profile.release]
debug = true lto = true
opt-level = 's'
# debug = true
# [profile.release]
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
+29
View File
@@ -37,3 +37,32 @@ static C2: FC<()> = |ctx| {
} }
}) })
}; };
static DocExamples: FC<()> = |ctx| {
//
let is_ready = false;
let items = (0..10).map(|i| rsx! { li {"{i}"} });
let _ = rsx! {
ul {
{items}
}
};
rsx! {
div {}
h1 {}
{""}
"asbasd"
dioxus::Fragment {
//
}
}
ctx.render(rsx! {
div {
{ is_ready.then(|| rsx!{ h1 {"We are ready!"} }) }
}
})
};
+5 -2
View File
@@ -8,14 +8,17 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
} }
// Use `wee_alloc` as the global allocator.
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
fn App(ctx: Context<()>) -> VNode { fn App(ctx: Context<()>) -> VNode {
let cansee = use_state_new(&ctx, || false); let cansee = use_state_new(&ctx, || false);
rsx! { in ctx, rsx! { in ctx,
div { div {
"Shadow of the child:" "Shadow of the child:"
button { button { onclick: move |_| cansee.set(!**cansee)
"Gaze into the void" "Gaze into the void"
onclick: move |_| cansee.set(!**cansee)
} }
{cansee.then(|| rsx!{ Child {} })} {cansee.then(|| rsx!{ Child {} })}
} }
+9 -15
View File
@@ -1,13 +1,14 @@
//! Basic example that renders a simple VNode to the browser. //! Basic example that renders a simple VNode to the browser.
use std::rc::Rc; use std::{future::Future, pin::Pin, rc::Rc};
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_web::*; use dioxus_web::*;
fn main() { fn main() {
// Setup logging // Setup logging and panic handling
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
// Run the app // Run the app
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
} }
@@ -16,23 +17,16 @@ static App: FC<()> = |ctx| {
let (contents, set_contents) = use_state(&ctx, || "asd"); let (contents, set_contents) = use_state(&ctx, || "asd");
ctx.render(rsx! { ctx.render(rsx! {
div { div { class: "flex items-center justify-center flex-col"
class: "flex items-center justify-center flex-col" div { class: "flex items-center justify-center"
div { div { class: "flex flex-col bg-white rounded p-4 w-full max-w-xs"
class: "flex items-center justify-center"
div {
class: "flex flex-col bg-white rounded p-4 w-full max-w-xs"
div { class: "font-bold text-xl", "Example Web app" } div { class: "font-bold text-xl", "Example Web app" }
div { class: "text-sm text-gray-500", "This is running in your browser!" } div { class: "text-sm text-gray-500", "This is running in your browser!" }
div { div { class: "flex flex-row items-center justify-center mt-6"
class: "flex flex-row items-center justify-center mt-6"
div { class: "font-medium text-6xl", "100%" } div { class: "font-medium text-6xl", "100%" }
} }
div { div { class: "flex flex-row justify-between mt-6"
class: "flex flex-row justify-between mt-6" a { href: "https://www.dioxuslabs.com", class: "underline"
a {
href: "https://www.dioxuslabs.com"
class: "underline"
"Made with dioxus" "Made with dioxus"
} }
} }
+1 -13
View File
@@ -28,17 +28,10 @@ pub struct TodoItem {
static App: FC<()> = |ctx| { static App: FC<()> = |ctx| {
let (draft, set_draft) = use_state(&ctx, || "".to_string()); let (draft, set_draft) = use_state(&ctx, || "".to_string());
let (filter, set_filter) = use_state(&ctx, || FilterState::All); let (filter, set_filter) = use_state(&ctx, || FilterState::All);
let (is_editing, set_is_editing) = use_state(&ctx, || false);
// let (todos, set_todos) = use_state(&ctx, || BTreeMap::<String, TodoItem>::new());
// let todos = use_ref(&ctx, || BTreeMap::<String, TodoItem>::new());
let todos = use_state_new(&ctx, || BTreeMap::<uuid::Uuid, TodoItem>::new()); let todos = use_state_new(&ctx, || BTreeMap::<uuid::Uuid, TodoItem>::new());
// let blah = "{draft}"
ctx.render(rsx!( ctx.render(rsx!(
div { div {
id: "app" id: "app"
div { div {
header { header {
class: "header" class: "header"
@@ -60,7 +53,6 @@ static App: FC<()> = |ctx| {
input { input {
class: "new-todo" class: "new-todo"
placeholder: "What needs to be done?" placeholder: "What needs to be done?"
// value: "{draft}"
oninput: move |evt| set_draft(evt.value) oninput: move |evt| set_draft(evt.value)
} }
} }
@@ -76,17 +68,13 @@ static App: FC<()> = |ctx| {
.map(|(id, todo)| { .map(|(id, todo)| {
rsx!{ rsx!{
li { li {
key: "{id}"
"{todo.contents}" "{todo.contents}"
input { input {
class: "toggle" class: "toggle"
type: "checkbox" type: "checkbox"
"{todo.checked}" "{todo.checked}"
} }
// {is_editing.then(|| rsx!(
// input {
// value: "{contents}"
// }
// ))}
} }
} }
}) })