chore: rename ctx to cx

This commit is contained in:
Jonathan Kelley committed 2021-06-25 21:15:33 -04:00
1 parent 23c14078bb
commit 81382e7044
99 files changed
+789 -664

No files matched your search

+14 -14
View File
@@ -53,23 +53,23 @@ This atom of state is initialized with a value of `"Green"`. The atom that is re
This is then later used in components like so:
```rust
fn App(ctx: Context<()>) -> VNode {
fn App(cx: Context<()>) -> VNode {
// The Atom root must be initialized at the top of the application before any use_Atom hooks
dirac::intialize_root(&ctx, |_| {});
dirac::intialize_root(&cx, |_| {});
let color = dirac::use_read(&ctx, &LightColor);
let color = dirac::use_read(&cx, &LightColor);
ctx.render(rsx!( h1 {"Color of light: {color}"} ))
cx.render(rsx!( h1 {"Color of light: {color}"} ))
}
```
Atoms are considered "Writable" objects since any consumer may also set the Atom's value with their own:
```rust
fn App(ctx: Context<()>) -> VNode {
let color = dirac::use_read(&ctx, &LightColor);
let set_color = dirac::use_write(&ctx, &LightColor);
ctx.render(rsx!(
fn App(cx: Context<()>) -> VNode {
let color = dirac::use_read(&cx, &LightColor);
let set_color = dirac::use_write(&cx, &LightColor);
cx.render(rsx!(
h1 { "Color: {color}" }
button { onclick: move |_| set_color("red"), "red" }
button { onclick: move |_| set_color("yellow"), "yellow" }
@@ -81,9 +81,9 @@ fn App(ctx: Context<()>) -> VNode {
"Reading" a value with use_read subscribes that component to any changes to that value while "Writing" a value does not. It's a good idea to use `write-only` whenever it makes sense to prevent unnecessary evaluations. Both `read` and `write` may be combined together to provide a `use_state` style hook.
```rust
fn App(ctx: Context<()>) -> VNode {
let (color, set_color) = dirac::use_read_write(&ctx, &Light);
ctx.render(rsx!(
fn App(cx: Context<()>) -> VNode {
let (color, set_color) = dirac::use_read_write(&cx, &Light);
cx.render(rsx!(
h1 { "Color: {color}" }
button { onclick: move |_| set_color("red"), "red" }
))
@@ -154,9 +154,9 @@ const CloudRatings: AtomFamily<&str, i32> = |api| {
Whenever you `select` on a `Family`, the ID of the entry is tracked. Other subscribers will only be updated if they too select the same family with the same key and that value is updated. Otherwise, these subscribers will never re-render on an "insert", "remove", or "update" of the collection. You could easily implement this yourself with Atoms, immutable datastructures, and selectors, but our implementation is more efficient and first-class.
```rust
fn App(ctx: Context<()>) -> VNode {
let (rating, set_rating) = dirac::use_read_write(ctx, CloudRatings.select("AWS"));
ctx.render(rsx!(
fn App(cx: Context<()>) -> VNode {
let (rating, set_rating) = dirac::use_read_write(cx, CloudRatings.select("AWS"));
cx.render(rsx!(
h1 { "AWS rating: {rating}" }
button { onclick: move |_| set_rating((rating + 1) % 5), "incr" }
))
+5 -5
View File
@@ -28,12 +28,12 @@ impl TitleController {
}
fn main() {
wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(|ctx| {
let title = use_read(&ctx, &TITLE);
let subtitle = use_read(&ctx, &SUBTITLE);
let controller = TitleController::new(use_recoil_api(&ctx));
wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(|cx| {
let title = use_read(&cx, &TITLE);
let subtitle = use_read(&cx, &SUBTITLE);
let controller = TitleController::new(use_recoil_api(&cx));
rsx! { in ctx,
rsx! { in cx,
div {
"{title}"
"{subtitle}"
+4 -4
View File
@@ -19,11 +19,11 @@ fn update_title(api: &RecoilApi) {
}
}
static App: FC<()> = |ctx| {
let title = use_read(&ctx, &TITLE);
let next_light = use_recoil_api(&ctx, |api| move |_| update_title(&api));
static App: FC<()> = |cx| {
let title = use_read(&cx, &TITLE);
let next_light = use_recoil_api(&cx, |api| move |_| update_title(&api));
rsx! { in ctx,
rsx! { in cx,
div {
"{title}"
button { onclick: {next_light}, "Next light" }
+4 -4
View File
@@ -31,13 +31,13 @@ const TODOS: EcsModel<u32, TodoModel> = |builder| {};
// const SELECT_TITLE: SelectorBorrowed<u32, &str> = |s, k| TODOS.field(0).select(k);
// const SELECT_SUBTITLE: SelectorBorrowed<u32, &str> = |s, k| TODOS.field(1).select(k);
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {});
static App: FC<()> = |cx| {
use_init_recoil_root(cx, |_| {});
// let title = use_recoil_value(ctx, &C_SELECTOR);
// let title = use_recoil_value(cx, &C_SELECTOR);
let title = "";
rsx! { in ctx,
rsx! { in cx,
div {
"{title}"
// button { onclick: {next_light}, "Next light" }
+8 -8
View File
@@ -13,18 +13,18 @@ struct Todo {
content: String,
}
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, move |cfg| {});
static App: FC<()> = |cx| {
use_init_recoil_root(cx, move |cfg| {});
let todos = use_read_family(ctx, &TODOS);
let todos = use_read_family(cx, &TODOS);
// rsx! { in ctx,
// rsx! { in cx,
// div {
// h1 {"Basic Todolist with AtomFamilies in Recoil.rs"}
// ul { { todos.keys().map(|id| rsx! { Child { id: *id } }) } }
// }
// }
ctx.render(html! {
cx.render(html! {
<a href="#" class="">
<img class="inline-block h-10 w-10 rounded-full object-cover ring-2 ring-white" src="/images/person/4.jpg" alt="Jade"/>
</a>
@@ -36,10 +36,10 @@ struct ChildProps {
id: Uuid,
}
static Child: FC<ChildProps> = |ctx| {
let (todo, set_todo) = use_read_write(ctx, &TODOS.select(&ctx.id));
static Child: FC<ChildProps> = |cx| {
let (todo, set_todo) = use_read_write(cx, &TODOS.select(&cx.id));
rsx! { in ctx,
rsx! { in cx,
li {
h1 {"{todo.title}"}
input { type: "checkbox", name: "scales", checked: "{todo.checked}" }
+8 -8
View File
@@ -12,11 +12,11 @@ struct Todo {
contents: String,
}
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {});
let todos = use_read(&ctx, &TODOS);
static App: FC<()> = |cx| {
use_init_recoil_root(cx, |_| {});
let todos = use_read(&cx, &TODOS);
rsx! { in ctx,
rsx! { in cx,
div {
"Basic Todolist with AtomFamilies in Recoil.rs"
}
@@ -28,11 +28,11 @@ struct ChildProps {
id: Uuid,
}
static Child: FC<ChildProps> = |ctx| {
let todo = use_read(ctx, &TODOS).get(&ctx.id).unwrap();
// let (todo, set_todo) = use_read_write(ctx, &TODOS);
static Child: FC<ChildProps> = |cx| {
let todo = use_read(cx, &TODOS).get(&cx.id).unwrap();
// let (todo, set_todo) = use_read_write(cx, &TODOS);
rsx! { in ctx,
rsx! { in cx,
div {
h1 {"{todo.title}"}
input { type: "checkbox", name: "scales", checked: "{todo.checked}" }
+4 -4
View File
@@ -3,12 +3,12 @@ use recoil::*;
const COUNT: Atom<i32> = |_| 0;
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {});
static App: FC<()> = |cx| {
use_init_recoil_root(cx, |_| {});
let (count, set_count) = use_read_write(&ctx, &COUNT);
let (count, set_count) = use_read_write(&cx, &COUNT);
rsx! { in ctx,
rsx! { in cx,
div {
"Count: {count}"
br {}
+4 -4
View File
@@ -17,12 +17,12 @@ const D_SELECTOR: SelectorFamilyBorrowed<i32, i32> = |api, key| -> &i32 {
a
};
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {});
static App: FC<()> = |cx| {
use_init_recoil_root(cx, |_| {});
let title = use_read(ctx, &C_SELECTOR);
let title = use_read(cx, &C_SELECTOR);
rsx! { in ctx,
rsx! { in cx,
div {
"{title}"
// button { onclick: {next_light}, "Next light" }
+12 -12
View File
@@ -5,9 +5,9 @@ const A: Atom<i32> = |_| 0;
const B: Atom<i32> = |_| 0;
const C: Selector<i32> = |api| api.get(&A) + api.get(&B);
static App: FC<()> = |ctx| {
use_init_recoil_root(ctx, |_| {});
rsx! { in ctx,
static App: FC<()> = |cx| {
use_init_recoil_root(cx, |_| {});
rsx! { in cx,
div {
Banner {}
BtnA {}
@@ -16,14 +16,14 @@ static App: FC<()> = |ctx| {
}
};
static Banner: FC<()> = |ctx| {
let count = use_read(&ctx, &C);
ctx.render(rsx! { h1 { "Count: {count}" } })
static Banner: FC<()> = |cx| {
let count = use_read(&cx, &C);
cx.render(rsx! { h1 { "Count: {count}" } })
};
static BtnA: FC<()> = |ctx| {
let (a, set) = use_read_write(&ctx, &A);
rsx! { in ctx,
static BtnA: FC<()> = |cx| {
let (a, set) = use_read_write(&cx, &A);
rsx! { in cx,
div { "a"
button { "+", onclick: move |_| set(a + 1) }
button { "-", onclick: move |_| set(a - 1) }
@@ -31,9 +31,9 @@ static BtnA: FC<()> = |ctx| {
}
};
static BtnB: FC<()> = |ctx| {
let (b, set) = use_read_write(&ctx, &B);
rsx! { in ctx,
static BtnB: FC<()> = |cx| {
let (b, set) = use_read_write(&cx, &B);
rsx! { in cx,
div { "b"
button { "+", onclick: move |_| set(b + 1) }
button { "-", onclick: move |_| set(b - 1) }
+1 -1
View File
@@ -2,7 +2,7 @@ fn main() {}
use dioxus_core::prelude::*;
static App: FC<()> = |ctx| {
static App: FC<()> = |cx| {
//
use_initialize_app()
};
@@ -13,23 +13,23 @@ use std::future::Future;
use dioxus_core::prelude::*;
static App: FC<()> = |ctx| {
static App: FC<()> = |cx| {
//
let title = use_async_atom();
let title_card = suspend(&ctx, title, move |val| {
let title_card = suspend(&cx, title, move |val| {
//
rsx!(in ctx, div {
rsx!(in cx, 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}" } ))
// let title_card2 = cx.suspend(fut, move |(text, text2)| {
// cx.render(rsx!( h3 { "{text}" } ))
// });
ctx.render(rsx! {
cx.render(rsx! {
div {
{title_card}
// {title_card2}
+5 -5
View File
@@ -64,7 +64,7 @@ Also, we want selectors to have internal dependencies.
## Async atoms
```rust
let (atom, set_atom, modify_atom) = (ATOM.use_read(ctx), ATOM.use_write(ctx), ATOM.use_modify(ctx));
let (atom, set_atom, modify_atom) = (ATOM.use_read(cx), ATOM.use_write(cx), ATOM.use_modify(cx));
const Title: AsyncAtom<String> = |builder| {
builder.on_set(|api, new_val| async {
@@ -93,10 +93,10 @@ const ContentCards: SelectorFamily<Uuid, ContentCard> = |api, key| api.on_get_as
data
})
static ContentCard: FC<()> = |ctx| {
let body = async match use_recoil_value()(ctx.id).await {
Ok(content) => rsx!{in ctx, p {"{content}"} }
Err(e) => rsx!{in ctx, p {"Failed to load"}}
static ContentCard: FC<()> = |cx| {
let body = async match use_recoil_value()(cx.id).await {
Ok(content) => rsx!{in cx, p {"{content}"} }
Err(e) => rsx!{in cx, p {"Failed to load"}}
};
rsx!{
+35 -35
View File
@@ -31,15 +31,15 @@ mod traits {
// Atoms, selectors, and their family variants are readable
pub trait Readable<T: AtomValue>: Sized + Copy {
fn use_read<'a, P: 'static>(self, ctx: Context<'a, P>) -> &'a T {
hooks::use_read(&ctx, self)
fn use_read<'a, P: 'static>(self, cx: Context<'a, P>) -> &'a T {
hooks::use_read(&cx, self)
}
// This returns a future of the value
// If the atom is currently pending, that future will resolve to pending
// If the atom is currently ready, the future will immediately resolve
// if the atom switches from ready to pending, the component will re-run, returning a pending future
fn use_read_async<'a, P>(self, ctx: Context<'a, P>) -> &'a T {
fn use_read_async<'a, P>(self, cx: Context<'a, P>) -> &'a T {
todo!()
}
@@ -53,11 +53,11 @@ mod traits {
// Only atoms and atom families are writable
// Selectors and selector families are not
pub trait Writable<T: AtomValue>: Readable<T> + Sized {
fn use_read_write<'a, P>(self, ctx: Context<'a, P>) -> (&'a T, &'a Rc<dyn Fn(T)>) {
fn use_read_write<'a, P>(self, cx: Context<'a, P>) -> (&'a T, &'a Rc<dyn Fn(T)>) {
todo!()
}
fn use_write<'a, P>(self, ctx: Context<'a, P>) -> &'a Rc<dyn Fn(T)> {
fn use_write<'a, P>(self, cx: Context<'a, P>) -> &'a Rc<dyn Fn(T)> {
todo!()
}
}
@@ -91,13 +91,13 @@ mod atoms {
use super::*;
use dioxus_core::prelude::Context;
fn _test(ctx: Context<()>) {
fn _test(cx: Context<()>) {
const EXAMPLE_ATOM: Atom<i32> = |_| 10;
// ensure that atoms are both read and write
let _ = use_read(&ctx, &EXAMPLE_ATOM);
let _ = use_read_write(&ctx, &EXAMPLE_ATOM);
let _ = use_write(&ctx, &EXAMPLE_ATOM);
let _ = use_read(&cx, &EXAMPLE_ATOM);
let _ = use_read_write(&cx, &EXAMPLE_ATOM);
let _ = use_write(&cx, &EXAMPLE_ATOM);
}
}
}
@@ -159,9 +159,9 @@ mod atomfamily {
use super::*;
const Titles: AtomHashMap<u32, &str> = |map| {};
fn test(ctx: Context<()>) {
let title = Titles.select(&10).use_read(ctx);
let t2 = use_read(&ctx, &Titles.select(&10));
fn test(cx: Context<()>) {
let title = Titles.select(&10).use_read(cx);
let t2 = use_read(&cx, &Titles.select(&10));
}
}
}
@@ -370,8 +370,8 @@ mod hooks {
use super::*;
use dioxus_core::{hooks::use_ref, prelude::Context, virtual_dom::Scoped};
pub fn use_init_recoil_root<P>(ctx: Context<P>, cfg: impl Fn(())) {
ctx.use_create_context(move || RefCell::new(RecoilRoot::new()))
pub fn use_init_recoil_root<P>(cx: Context<P>, cfg: impl Fn(())) {
cx.use_create_context(move || RefCell::new(RecoilRoot::new()))
}
/// Gain access to the recoil API directly - set, get, modify, everything
@@ -381,17 +381,17 @@ mod hooks {
///
/// You can use this method to create controllers that perform much more complex actions than set/get
/// However, be aware that "getting" values through this hook will not subscribe the component to any updates.
pub fn use_recoil_api<'a>(ctx: &impl Scoped<'a>) -> &'a Rc<RecoilContext> {
ctx.use_context::<RecoilContext>()
pub fn use_recoil_api<'a>(cx: &impl Scoped<'a>) -> &'a Rc<RecoilContext> {
cx.use_context::<RecoilContext>()
}
pub fn use_write<'a, T: AtomValue>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
// todo: this shouldn't need to be static
writable: impl Writable<T>,
) -> &'a Rc<dyn Fn(T)> {
let api = use_recoil_api(ctx);
ctx.use_hook(
let api = use_recoil_api(cx);
cx.use_hook(
move || {
let api = api.clone();
let raw_id = writable.static_id();
@@ -413,7 +413,7 @@ mod hooks {
/// This is useful if you need the memoized Atom value. However, Rc<T> is not as easy to
/// work with as
pub fn use_read_raw<'a, T: AtomValue>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
readable: impl Readable<T>,
) -> &'a Rc<T> {
struct ReadHook<T> {
@@ -421,12 +421,12 @@ mod hooks {
consumer_id: u32,
}
let api = use_recoil_api(ctx);
ctx.use_hook(
let api = use_recoil_api(cx);
cx.use_hook(
move || {
let mut api = api.as_ref().borrow_mut();
let update = ctx.schedule_update();
let update = cx.schedule_update();
let val = api.try_get_raw(readable).unwrap();
let id = api.subscribe(readable, update);
ReadHook {
@@ -449,8 +449,8 @@ mod hooks {
}
///
pub fn use_read<'a, T: AtomValue>(ctx: &impl Scoped<'a>, readable: impl Readable<T>) -> &'a T {
use_read_raw(ctx, readable).as_ref()
pub fn use_read<'a, T: AtomValue>(cx: &impl Scoped<'a>, readable: impl Readable<T>) -> &'a T {
use_read_raw(cx, readable).as_ref()
}
/// # Use an atom in both read and write
@@ -463,16 +463,16 @@ mod hooks {
///
/// ```
/// const Title: Atom<&str> = |_| "hello";
/// let (title, set_title) = use_read_write(ctx, &Title);
/// let (title, set_title) = use_read_write(cx, &Title);
///
/// // equivalent to:
/// let (title, set_title) = (use_read(ctx, &Title), use_write(ctx, &Title));
/// let (title, set_title) = (use_read(cx, &Title), use_write(cx, &Title));
/// ```
pub fn use_read_write<'a, T: AtomValue + 'static>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
writable: impl Writable<T>,
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
(use_read(ctx, writable), use_write(ctx, writable))
(use_read(cx, writable), use_write(cx, writable))
}
/// # Modify an atom without using `use_read`.
@@ -491,12 +491,12 @@ mod hooks {
/// ## Example
///
/// ```ignore
/// let modify_atom = use_modify(ctx, Atom);
/// let modify_atom = use_modify(cx, Atom);
///
/// modify_atom(&|a| *a += 1)
/// ```
pub fn use_modify<'a, T: AtomValue + 'static + Clone, P>(
ctx: Context<'a, P>,
cx: Context<'a, P>,
writable: impl Writable<T>,
) -> impl Fn(&dyn Fn()) {
|_| {}
@@ -506,7 +506,7 @@ mod hooks {
/// !! Any changes to the family will cause this subscriber to update
/// Try not to put this at the very top-level of your app.
pub fn use_read_family<'a, K, V, P>(
ctx: Context<'a, P>,
cx: Context<'a, P>,
t: &AtomHashMap<K, V>,
) -> &'a im_rc::HashMap<K, V> {
todo!()
@@ -532,9 +532,9 @@ mod utils {
pub fn RecoilApp<T: 'static>(
root: impl for<'a> Fn(Context<'a, T>) -> VNode,
) -> impl for<'a> Fn(Context<'a, T>) -> VNode {
move |ctx| {
use_init_recoil_root(ctx, |_| {});
root(ctx)
move |cx| {
use_init_recoil_root(cx, |_| {});
root(cx)
}
}
}
+3 -3
View File
@@ -133,7 +133,7 @@ impl ToTokens for FunctionComponent {
}
impl<'a> FC for #function_name<'a> {
fn render(ctx: Context<'_>, props: &#function_name<'a>) -> VNode {
fn render(cx: Context<'_>, props: &#function_name<'a>) -> VNode {
let #function_name {
..
} = props;
@@ -150,12 +150,12 @@ impl ToTokens for FunctionComponent {
// name: &'a str
// }
// pub fn component<'a>(ctx: &'a Context<'a, Props>) -> VNode<'a> {
// pub fn component<'a>(cx: &'a Context<'a, Props>) -> VNode<'a> {
// // Destructure the props into the parent scope
// // todo: handle expansion of lifetimes
// let Props {
// name
// } = ctx.props;
// } = cx.props;
// #block
// }
+5 -5
View File
@@ -39,7 +39,7 @@ impl Parse for HtmlRender {
return input.parse::<LitStr>()?.parse::<HtmlRender>();
}
// let ctx: Ident = s.parse()?;
// let cx: Ident = s.parse()?;
// s.parse::<Token![,]>()?;
// if elements are in an array, return a bumpalo::collections::Vec rather than a Node.
let kind = if input.peek(token::Bracket) {
@@ -64,8 +64,8 @@ impl ToTokens for HtmlRender {
// create a lazy tree that accepts a bump allocator
let final_tokens = quote! {
dioxus::prelude::LazyNodes::new(move |ctx| {
let bump = &ctx.bump();
dioxus::prelude::LazyNodes::new(move |cx| {
let bump = &cx.bump();
#new_toks
})
@@ -152,10 +152,10 @@ struct Element {
impl ToTokens for ToToksCtx<&Element> {
fn to_tokens(&self, tokens: &mut TokenStream2) {
// let ctx = self.ctx;
// let cx = self.cx;
let name = &self.inner.name.to_string();
tokens.append_all(quote! {
dioxus::builder::ElementBuilder::new(ctx, #name)
dioxus::builder::ElementBuilder::new(cx, #name)
});
for attr in self.inner.attrs.iter() {
self.recurse(attr).to_tokens(tokens);
+2 -2
View File
@@ -61,8 +61,8 @@ pub fn html_template(s: TokenStream) -> TokenStream {
/// ```ignore
///
/// #[fc]
/// fn Example(ctx: Context, name: &str) -> VNode {
/// ctx.render(rsx! { h1 {"hello {name}"} })
/// fn Example(cx: Context, name: &str) -> VNode {
/// cx.render(rsx! { h1 {"hello {name}"} })
/// }
/// ```
#[proc_macro_attribute]
+2 -2
View File
@@ -120,14 +120,14 @@ impl ToTokens for Component {
let childs = &self.children;
let children = quote! {
ChildrenList::new(__ctx)
ChildrenList::new(__cx)
#( .add_child(#childs) )*
.finish()
};
tokens.append_all(quote! {
dioxus::builder::virtual_child(
__ctx,
__cx,
#name,
#builder,
#key_token,
+3 -3
View File
@@ -68,7 +68,7 @@ impl ToTokens for Element {
let name = &self.name.to_string();
tokens.append_all(quote! {
dioxus::builder::ElementBuilder::new(__ctx, #name)
dioxus::builder::ElementBuilder::new(__cx, #name)
});
for attr in self.attrs.iter() {
@@ -221,13 +221,13 @@ impl ToTokens for ElementAttr {
}
AttrType::Event(event) => {
tokens.append_all(quote! {
.add_listener(dioxus::events::on::#nameident(__ctx, #event))
.add_listener(dioxus::events::on::#nameident(__cx, #event))
});
}
AttrType::EventTokens(event) => {
//
tokens.append_all(quote! {
.add_listener(dioxus::events::on::#nameident(__ctx, #event))
.add_listener(dioxus::events::on::#nameident(__cx, #event))
});
}
}
+2 -2
View File
@@ -50,14 +50,14 @@ impl ToTokens for Fragment {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let childs = &self.children;
let children = quote! {
ChildrenList::new(__ctx)
ChildrenList::new(__cx)
#( .add_child(#childs) )*
.finish()
};
tokens.append_all(quote! {
// #key_token,
dioxus::builder::vfragment(
__ctx,
__cx,
None,
#children
)
+7 -7
View File
@@ -81,14 +81,14 @@ impl ToTokens for RsxRender {
} else {
let childs = &self.roots;
let children = quote! {
ChildrenList::new(__ctx)
ChildrenList::new(__cx)
#( .add_child(#childs) )*
.finish()
};
quote! {
// #key_token,
dioxus::builder::vfragment(
__ctx,
__cx,
None,
#children
)
@@ -96,17 +96,17 @@ impl ToTokens for RsxRender {
};
match &self.custom_context {
// The `in ctx` pattern allows directly rendering
// The `in cx` pattern allows directly rendering
Some(ident) => out_tokens.append_all(quote! {
#ident.render(dioxus::prelude::LazyNodes::new(move |__ctx|{
let bump = &__ctx.bump();
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx|{
let bump = &__cx.bump();
#inner
}))
}),
// Otherwise we just build the LazyNode wrapper
None => out_tokens.append_all(quote! {
dioxus::prelude::LazyNodes::new(move |__ctx|{
let bump = &__ctx.bump();
dioxus::prelude::LazyNodes::new(move |__cx|{
let bump = &__cx.bump();
#inner
})
}),
+3 -3
View File
@@ -46,7 +46,7 @@ impl Parse for RsxTemplate {
// let new_stream = TokenStream::from(t.to_s)
// let ctx: Ident = s.parse()?;
// let cx: Ident = s.parse()?;
// s.parse::<Token![,]>()?;
// if elements are in an array, return a bumpalo::collections::Vec rather than a Node.
// let kind = if s.peek(token::Bracket) {
@@ -72,8 +72,8 @@ impl ToTokens for RsxTemplate {
// // create a lazy tree that accepts a bump allocator
// let final_tokens = quote! {
// dioxus::prelude::LazyNodes::new(move |ctx| {
// let bump = &ctx.bump();
// dioxus::prelude::LazyNodes::new(move |cx| {
// let bump = &cx.bump();
// #new_toks
// })
+3
View File
@@ -40,6 +40,9 @@ serde = { version="1", features=["derive"], optional=true }
smallvec = "1.6.1"
futures = "0.3.15"
[features]
default = []
serialize = ["serde", "generational-arena/serde"]
+9 -9
View File
@@ -2,10 +2,10 @@ fn main() {}
use dioxus_core::prelude::*;
static Example: FC<()> = |ctx| {
ctx.render(dioxus_core::prelude::LazyNodes::new(move |ctx| {
let bump = ctx.bump();
dioxus_core::builder::ElementBuilder::new(ctx, "h1")
static Example: FC<()> = |cx| {
cx.render(dioxus_core::prelude::LazyNodes::new(move |cx| {
let bump = cx.bump();
dioxus_core::builder::ElementBuilder::new(cx, "h1")
.children([dioxus_core::builder::text3(bump, format_args!("hello"))])
.finish()
}))
@@ -14,13 +14,13 @@ static Example: FC<()> = |ctx| {
struct Props {
text: String,
}
static Example2: FC<Props> = |ctx| {
ctx.render(dioxus_core::prelude::LazyNodes::new(move |__ctx| {
let bump = __ctx.bump();
dioxus_core::builder::ElementBuilder::new(__ctx, "h1")
static Example2: FC<Props> = |cx| {
cx.render(dioxus_core::prelude::LazyNodes::new(move |__cx| {
let bump = __cx.bump();
dioxus_core::builder::ElementBuilder::new(__cx, "h1")
.children([dioxus_core::builder::text3(
bump,
format_args!("{}", ctx.props.text),
format_args!("{}", cx.props.text),
)])
.finish()
}))
+8 -8
View File
@@ -19,15 +19,15 @@ struct ListItem {
age: u32,
}
fn app(ctx: Context<AppProps>) -> VNode {
let (val, set_val) = use_state(&ctx, || 0);
fn app(cx: Context<AppProps>) -> VNode {
let (val, set_val) = use_state(&cx, || 0);
ctx.render(LazyNodes::new(move |_nodectx| {
builder::ElementBuilder::new(_nodectx, "div")
cx.render(LazyNodes::new(move |_nodecx| {
builder::ElementBuilder::new(_nodecx, "div")
.iter_child({
ctx.items.iter().map(|child| {
cx.items.iter().map(|child| {
builder::virtual_child(
_nodectx,
_nodecx,
ChildItem,
ChildProps {
item: child.clone(),
@@ -38,8 +38,8 @@ fn app(ctx: Context<AppProps>) -> VNode {
)
})
})
.iter_child([builder::ElementBuilder::new(_nodectx, "div")
.iter_child([builder::text3(_nodectx.bump(), format_args!("{}", val))])
.iter_child([builder::ElementBuilder::new(_nodecx, "div")
.iter_child([builder::text3(_nodecx.bump(), format_args!("{}", val))])
.finish()])
.finish()
}))
+5 -5
View File
@@ -13,21 +13,21 @@ struct Props {
static Example: FC<Props> = |cpt| {
todo!()
// let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap());
// let value = cx.use_context(|c: &SomeContext| c.items.last().unwrap());
// ctx.render(LazyNodes::new(move |bump| {
// cx.render(LazyNodes::new(move |bump| {
// builder::ElementBuilder::new(bump, "button")
// .on("click", move |_| {
// println!("Value is {}", ctx.name);
// println!("Value is {}", cx.name);
// println!("Value is {}", value.as_str());
// println!("Value is {}", *value);
// })
// .on("click", move |_| {
// println!("Value is {}", ctx.name);
// println!("Value is {}", cx.name);
// })
// .finish()
// }))
// ctx.render(html! {
// cx.render(html! {
// <div>
// <button onclick={move |_| println!("Value is {}", value)} />
// <button onclick={move |_| println!("Value is {}", value)} />
+12 -12
View File
@@ -34,7 +34,7 @@ fn main() {}
// 2: Trees are not evaluated
// */
// let example_caller = move |ctx: &Bump| {
// let example_caller = move |cx: &Bump| {
// todo!()
// // let p = Props { blah: true, text };
// // let c = Context { props: &p };
@@ -57,11 +57,11 @@ fn main() {}
// }
// }
// fn component<'a>(ctx: Context<'a, Props>) -> VNode<'a> {
// fn component<'a>(cx: Context<'a, Props>) -> VNode<'a> {
// // Write asynchronous rendering code that immediately returns a "suspended" VNode
// // The concurrent API will then progress this component when the future finishes
// // You can suspend the entire component, or just parts of it
// let product_list = ctx.suspend(async {
// let product_list = cx.suspend(async {
// // Suspend the rendering that completes when the future is done
// match fetch_data().await {
// Ok(data) => html! { <div> "success!" </div>},
@@ -70,7 +70,7 @@ fn main() {}
// });
// // todo!()
// ctx.render(html! {
// cx.render(html! {
// <div>
// <h1> "Products" </h1>
// <button> "hello!" </button>
@@ -82,27 +82,27 @@ fn main() {}
// })
// }
// fn BuilderComp<'a>(ctx: Context<'a, Props>) -> VNode<'a> {
// fn BuilderComp<'a>(cx: Context<'a, Props>) -> VNode<'a> {
// // VNodes can be constructed via a builder or the html! macro
// // However, both of these are "lazy" - they need to be evaluated (aka, "viewed")
// // We can "view" them with Context for ultimate speed while inside components
// ctx.render(|bump| {
// cx.render(|bump| {
// div(bump)
// .attr("class", "edit")
// .child(text("Hello"))
// .child(text(ctx.ctx.text.as_ref()))
// .child(text(cx.cx.text.as_ref()))
// .finish()
// })
// }
// #[fc]
// fn EffcComp(ctx: Context, name: &str) -> VNode {
// fn EffcComp(cx: Context, name: &str) -> VNode {
// // VNodes can be constructed via a builder or the html! macro
// // However, both of these are "lazy" - they need to be evaluated (aka, "viewed")
// // We can "view" them with Context for ultimate speed while inside components
// // use "phase" style allocation;
// ctx.render(html! {
// cx.render(html! {
// <div>
// // your template goes here
// // feel free to directly use "name"
@@ -110,8 +110,8 @@ fn main() {}
// })
// }
// fn FullySuspended<'a>(ctx: &'a Context<Props>) -> VNode<'a> {
// ctx.suspend(async {
// fn FullySuspended<'a>(cx: &'a Context<Props>) -> VNode<'a> {
// cx.suspend(async {
// let i: i32 = 0;
// // full suspended works great with just returning VNodes!
@@ -123,7 +123,7 @@ fn main() {}
// _ => html! { <div> </div> },
// };
// if ctx.ctx.blah {
// if cx.cx.blah {
// html! { <div> </div> }
// } else {
// tex
+4 -4
View File
@@ -3,7 +3,7 @@
//!
//! Note - using the builder pattern does not required the Properties trait to be implemented - the only thing that matters is
//! if the type suppports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
//! that ensures compile-time required and optional fields on ctx.
//! that ensures compile-time required and optional fields on cx.
use crate::innerlude::FC;
@@ -50,9 +50,9 @@ pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
/// Fragments are incredibly useful when necessary, but *do* add cost in the diffing phase.
/// Try to avoid nesting fragments if you can. Infinitely nested Fragments *will* cause diffing to crash.
#[allow(non_upper_case_globals)]
pub const Fragment: FC<()> = |ctx| {
pub const Fragment: FC<()> = |cx| {
use crate::prelude::*;
ctx.render(LazyNodes::new(move |c| {
crate::nodebuilder::vfragment(c, None, ctx.children())
cx.render(LazyNodes::new(move |c| {
crate::nodebuilder::vfragment(c, None, cx.children())
}))
};
+3 -3
View File
@@ -86,7 +86,7 @@ impl DebugVNodeSource {
}
fn render_nodes(&self) -> VNode {
// let ctx = NodeCtx
// let cx = NodeCtx
todo!()
}
}
@@ -97,9 +97,9 @@ mod tests {
#[test]
fn ensure_creation() -> Result<(), ()> {
// static Example: FC<()> = |ctx| {
// static Example: FC<()> = |cx| {
// //
// ctx.render(html! { <div> "hello world" </div> })
// cx.render(html! { <div> "hello world" </div> })
// };
// let mut dom = VirtualDom::new(Example);
+3
View File
@@ -44,6 +44,9 @@ pub enum VirtualEvent {
MouseEvent(Rc<dyn on::MouseEvent>),
PointerEvent(Rc<dyn on::PointerEvent>),
// Whenever a task is ready (complete) Dioxus produces this "FiberEvent"
FiberEvent { task_id: u16 },
// image event has conflicting method types
// ImageEvent(event_data::ImageEvent),
OtherEvent,
+20 -20
View File
@@ -28,8 +28,8 @@ mod use_state_def {
///
/// Usage:
/// ```ignore
/// static Example: FC<()> = |ctx| {
/// let (counter, set_counter) = use_state(&ctx, || 0);
/// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0);
/// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1);
///
@@ -43,7 +43,7 @@ mod use_state_def {
/// }
/// ```
pub fn use_state<'a, 'c, T: 'static, F: FnOnce() -> T>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: F,
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
struct UseState<T: 'static> {
@@ -52,7 +52,7 @@ mod use_state_def {
caller: Rc<dyn Fn(T) + 'static>,
}
ctx.use_hook(
cx.use_hook(
move || UseState {
new_val: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -61,7 +61,7 @@ mod use_state_def {
move |hook| {
log::debug!("Use_state set called");
let inner = hook.new_val.clone();
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// get ownership of the new val and replace the current with the new
// -> as_ref -> borrow_mut -> deref_mut -> take
@@ -155,8 +155,8 @@ mod new_use_state_def {
///
/// Usage:
/// ```ignore
/// static Example: FC<()> = |ctx| {
/// let (counter, set_counter) = use_state(&ctx, || 0);
/// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0);
/// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1);
///
@@ -170,10 +170,10 @@ mod new_use_state_def {
/// }
/// ```
pub fn use_state_new<'a, 'c, T: 'static, F: FnOnce() -> T>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: F,
) -> &'a UseState<T> {
ctx.use_hook(
cx.use_hook(
move || UseState {
modifier: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -182,7 +182,7 @@ mod new_use_state_def {
},
move |hook| {
log::debug!("addr of hook: {:#?}", hook as *const _);
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// log::debug!("Checking if new value {:#?}", &hook.current_val);
// get ownership of the new val and replace the current with the new
@@ -247,10 +247,10 @@ mod use_ref_def {
/// Modifications to this value do not cause updates to the component
/// Attach to inner context reference, so context can be consumed
pub fn use_ref<'a, T: 'static>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: impl FnOnce() -> T + 'static,
) -> &'a RefCell<T> {
ctx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
cx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
}
}
@@ -271,11 +271,11 @@ mod use_reducer_def {
/// This is behaves almost exactly the same way as React's "use_state".
///
pub fn use_reducer<'a, 'c, State: 'static, Action: 'static>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: impl FnOnce() -> State,
_reducer: impl Fn(&mut State, Action),
) -> (&'a State, &'a Box<dyn Fn(Action)>) {
ctx.use_hook(
cx.use_hook(
move || UseReducer {
new_val: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -283,7 +283,7 @@ mod use_reducer_def {
},
move |hook| {
let _inner = hook.new_val.clone();
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// get ownership of the new val and replace the current with the new
// -> as_ref -> borrow_mut -> deref_mut -> take
@@ -320,9 +320,9 @@ mod use_reducer_def {
}
// #[allow(unused)]
// static Example: FC<()> = |ctx| {
// static Example: FC<()> = |cx| {
// let (count, reduce) = use_reducer(
// &ctx,
// &cx,
// || 0,
// |count, action| match action {
// Actions::Incr => *count += 1,
@@ -330,7 +330,7 @@ mod use_reducer_def {
// },
// );
// ctx.render(rsx! {
// cx.render(rsx! {
// div {
// h1 {"Count: {count}"}
// button {
@@ -347,8 +347,8 @@ mod use_reducer_def {
}
}
pub fn use_is_initialized<P>(ctx: Context<P>) -> bool {
let val = use_ref(&ctx, || false);
pub fn use_is_initialized<P>(cx: Context<P>) -> bool {
let val = use_ref(&cx, || false);
match *val.borrow() {
true => true,
false => {
+39 -38
View File
@@ -29,13 +29,14 @@ where
Attributes: 'a + AsRef<[Attribute<'a>]>,
Children: 'a + AsRef<[VNode<'a>]>,
{
ctx: &'b NodeCtx<'a>,
cx: &'b NodeCtx<'a>,
key: NodeKey<'a>,
tag_name: &'a str,
tag_name: &'static str,
// tag_name: &'a str,
listeners: Listeners,
attributes: Attributes,
children: Children,
namespace: Option<&'a str>,
namespace: Option<&'static str>,
}
impl<'a, 'b>
@@ -70,10 +71,10 @@ impl<'a, 'b>
/// let my_element_builder = ElementBuilder::new(&b, tag_name);
/// # fn flip_coin() -> bool { true }
/// ```
pub fn new(ctx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
let bump = ctx.bump();
pub fn new(cx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
let bump = cx.bump();
ElementBuilder {
ctx,
cx,
key: NodeKey::NONE,
tag_name,
listeners: bumpalo::collections::Vec::new_in(bump),
@@ -124,7 +125,7 @@ where
L: 'a + AsRef<[Listener<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners,
@@ -163,7 +164,7 @@ where
A: 'a + AsRef<[Attribute<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -202,7 +203,7 @@ where
C: 'a + AsRef<[VNode<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -227,9 +228,9 @@ where
/// .finish();
/// ```
#[inline]
pub fn namespace(self, namespace: Option<&'a str>) -> Self {
pub fn namespace(self, namespace: Option<&'static str>) -> Self {
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -281,7 +282,7 @@ where
Some(static_str) => static_str,
None => {
use bumpalo::core_alloc::fmt::Write;
let mut s = bumpalo::collections::String::new_in(self.ctx.bump());
let mut s = bumpalo::collections::String::new_in(self.cx.bump());
s.write_fmt(args).unwrap();
s.into_bump_str()
}
@@ -307,7 +308,7 @@ where
/// ```
#[inline]
pub fn finish(self) -> VNode<'a> {
let bump = self.ctx.bump();
let bump = self.cx.bump();
let children: &'a Children = bump.alloc(self.children);
let children: &'a [VNode<'a>] = children.as_ref();
@@ -357,11 +358,11 @@ where
/// .finish();
/// ```
pub fn on(self, event: &'static str, callback: impl Fn(VirtualEvent) + 'a) -> Self {
let bump = &self.ctx.bump();
let bump = &self.cx.bump();
let listener = Listener {
event,
callback: bump.alloc(callback),
scope: self.ctx.scope_ref.arena_idx,
scope: self.cx.scope_ref.arena_idx,
mounted_node: bump.alloc(Cell::new(RealDomNode::empty())),
};
self.add_listener(listener)
@@ -371,15 +372,15 @@ where
self.listeners.push(listener);
// bump the context id forward
let id = self.ctx.listener_id.get();
self.ctx.listener_id.set(id + 1);
let id = self.cx.listener_id.get();
self.cx.listener_id.set(id + 1);
// Add this listener to the context list
// This casts the listener to a self-referential pointer
// This is okay because the bump arena is stable
self.listeners.last().map(|g| {
let r = unsafe { std::mem::transmute::<&Listener<'a>, &Listener<'static>>(g) };
self.ctx
self.cx
.scope_ref
.listeners
.borrow_mut()
@@ -413,7 +414,7 @@ where
Some(static_str) => static_str,
None => {
use bumpalo::core_alloc::fmt::Write;
let mut s = bumpalo::collections::String::new_in(self.ctx.bump());
let mut s = bumpalo::collections::String::new_in(self.cx.bump());
s.write_fmt(args).unwrap();
s.into_bump_str()
}
@@ -501,7 +502,7 @@ where
pub fn iter_child(mut self, nodes: impl IntoIterator<Item = impl IntoVNode<'a>>) -> Self {
let len_before = self.children.len();
for item in nodes {
let child = item.into_vnode(&self.ctx);
let child = item.into_vnode(&self.cx);
self.children.push(child);
}
if cfg!(debug_assertions) {
@@ -531,20 +532,20 @@ impl<'a> IntoIterator for VNode<'a> {
}
}
impl<'a> IntoVNode<'a> for VNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
self
}
}
impl<'a> IntoVNode<'a> for &VNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
// cloning is cheap since vnodes are just references into bump arenas
self.clone()
}
}
pub trait IntoVNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a>;
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a>;
}
pub trait VNodeBuilder<'a, G>: IntoIterator<Item = G>
@@ -590,8 +591,8 @@ impl<'a, G> IntoVNode<'a> for LazyNodes<'a, G>
where
G: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a,
{
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
(self.inner)(ctx)
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
(self.inner)(cx)
}
}
@@ -608,14 +609,14 @@ where
}
impl<'a> IntoVNode<'a> for () {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
}
}
impl<'a> IntoVNode<'a> for Option<()> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
}
@@ -679,7 +680,7 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> {
}
pub fn virtual_child<'a, T: Properties + 'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
f: FC<T>,
props: T,
key: Option<&'a str>, // key: NodeKey<'a>,
@@ -689,37 +690,37 @@ pub fn virtual_child<'a, T: Properties + 'a>(
// might override it with the props macro
// todo!()
VNode::Component(
ctx.bump()
.alloc(crate::nodes::VComponent::new(ctx, f, props, key, children)),
// ctx.bump()
cx.bump()
.alloc(crate::nodes::VComponent::new(cx, f, props, key, children)),
// cx.bump()
// .alloc(crate::nodes::VComponent::new(f, props, key)),
)
}
pub fn vfragment<'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
key: Option<&'a str>, // key: NodeKey<'a>,
children: &'a [VNode<'a>],
) -> VNode<'a> {
VNode::Fragment(ctx.bump().alloc(VFragment::new(key, children)))
VNode::Fragment(cx.bump().alloc(VFragment::new(key, children)))
}
pub struct ChildrenList<'a, 'b> {
ctx: &'b NodeCtx<'a>,
cx: &'b NodeCtx<'a>,
children: bumpalo::collections::Vec<'a, VNode<'a>>,
}
impl<'a, 'b> ChildrenList<'a, 'b> {
pub fn new(ctx: &'b NodeCtx<'a>) -> Self {
pub fn new(cx: &'b NodeCtx<'a>) -> Self {
Self {
ctx,
children: bumpalo::collections::Vec::new_in(ctx.bump()),
cx,
children: bumpalo::collections::Vec::new_in(cx.bump()),
}
}
pub fn add_child(mut self, nodes: impl IntoIterator<Item = impl IntoVNode<'a>>) -> Self {
for item in nodes {
let child = item.into_vnode(&self.ctx);
let child = item.into_vnode(&self.cx);
self.children.push(child);
}
self
+48 -11
View File
@@ -11,10 +11,8 @@ use crate::{
};
use bumpalo::Bump;
use std::{
any::Any,
cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter},
marker::PhantomData,
rc::Rc,
};
@@ -56,6 +54,43 @@ impl<'a> Clone for VNode<'a> {
}
}
impl<'old, 'new> VNode<'old> {
// performs a somewhat costly clone of this vnode into another bump
// this is used when you want to drag nodes from an old frame into a new frame
// There is no way to safely drag listeners over (no way to clone a closure)
//
// This method will only be called if a component was once a real node and then becomes suspended
fn deep_clone_to_new_bump(&self, new: &'new Bump) -> VNode<'new> {
match self {
VNode::Element(el) => {
let new_el: VElement<'new> = VElement {
key: NodeKey::NONE,
// key: el.key.clone(),
tag_name: el.tag_name,
// wipe listeners on deep clone, there's no way to know what other bump material they might be referencing (nodes, etc)
listeners: &[],
attributes: {
let attr_vec = bumpalo::collections::Vec::new_in(new);
attr_vec.into_bump_slice()
},
children: {
let attr_vec = bumpalo::collections::Vec::new_in(new);
attr_vec.into_bump_slice()
},
namespace: el.namespace.clone(),
dom_id: el.dom_id.clone(),
};
VNode::Element(new.alloc_with(move || new_el))
}
VNode::Text(_) => todo!(),
VNode::Fragment(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Component(_) => todo!(),
}
}
}
impl<'a> VNode<'a> {
/// Low-level constructor for making a new `Node` of type element with given
/// parts.
@@ -67,11 +102,11 @@ impl<'a> VNode<'a> {
pub fn element(
bump: &'a Bump,
key: NodeKey<'a>,
tag_name: &'a str,
tag_name: &'static str,
listeners: &'a [Listener<'a>],
attributes: &'a [Attribute<'a>],
children: &'a [VNode<'a>],
namespace: Option<&'a str>,
namespace: Option<&'static str>,
) -> VNode<'a> {
let element = bump.alloc_with(|| VElement {
key,
@@ -157,14 +192,16 @@ pub struct VText<'src> {
// ========================================================
// VElement (div, h1, etc), attrs, keys, listener handle
// ========================================================
#[derive(Clone)]
pub struct VElement<'a> {
/// Elements have a tag name, zero or more attributes, and zero or more
pub key: NodeKey<'a>,
pub tag_name: &'a str,
pub tag_name: &'static str,
pub listeners: &'a [Listener<'a>],
pub attributes: &'a [Attribute<'a>],
pub children: &'a [VNode<'a>],
pub namespace: Option<&'a str>,
pub namespace: Option<&'static str>,
pub dom_id: Cell<RealDomNode>,
}
@@ -298,13 +335,13 @@ impl<'a> VComponent<'a> {
///
/// If the CanMemo is `false`, then the macro will call the backup method which always defaults to "false"
pub fn new<P: Properties + 'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
component: FC<P>,
props: P,
key: Option<&'a str>,
children: &'a [VNode<'a>],
) -> Self {
let bump = ctx.bump();
let bump = cx.bump();
let user_fc = component as *const ();
let props = bump.alloc(props);
@@ -370,13 +407,13 @@ fn create_closure<'a, P: 'a>(
let g: Captured = Rc::new(move |scp: &Scope| -> VNode {
// cast back into the right lifetime
let safe_props: &'_ P = unsafe { &*(raw_props as *const P) };
// let ctx: Context<P2> = todo!();
let ctx: Context<P> = Context {
// let cx: Context<P2> = todo!();
let cx: Context<P> = Context {
props: safe_props,
scope: scp,
};
let g = component(ctx);
let g = component(cx);
let g2 = unsafe { std::mem::transmute(g) };
g2
});
+60 -26
View File
@@ -21,6 +21,7 @@
use crate::{arena::ScopeArena, innerlude::*};
use bumpalo::Bump;
use futures::FutureExt;
use generational_arena::Arena;
use std::{
any::{Any, TypeId},
@@ -55,7 +56,7 @@ pub struct VirtualDom {
#[doc(hidden)]
_root_caller: Rc<OpaqueComponent>,
// _root_caller: Rc<OpaqueComponent<'static>>,
/// Type of the original ctx. This is stored as TypeId so VirtualDom does not need to be generic.
/// Type of the original cx. This is stored as TypeId so VirtualDom does not need to be generic.
///
/// Whenver props need to be updated, an Error will be thrown if the new props do not
/// match the props used to create the VirtualDom.
@@ -90,12 +91,12 @@ impl VirtualDom {
/// ```ignore
/// // Directly from a closure
///
/// let dom = VirtualDom::new(|ctx| ctx.render(rsx!{ div {"hello world"} }));
/// let dom = VirtualDom::new(|cx| cx.render(rsx!{ div {"hello world"} }));
///
/// // or pass in...
///
/// let root = |ctx| {
/// ctx.render(rsx!{
/// let root = |cx| {
/// cx.render(rsx!{
/// div {"hello world"}
/// })
/// }
@@ -103,8 +104,8 @@ impl VirtualDom {
///
/// // or directly from a fn
///
/// fn Example(ctx: Context<()>) -> VNode {
/// ctx.render(rsx!{ div{"hello world"} })
/// fn Example(cx: Context<()>) -> VNode {
/// cx.render(rsx!{ div{"hello world"} })
/// }
///
/// let dom = VirtualDom::new(Example);
@@ -113,7 +114,7 @@ impl VirtualDom {
Self::new_with_props(root, ())
}
/// Start a new VirtualDom instance with a dependent ctx.
/// Start a new VirtualDom instance with a dependent cx.
/// Later, the props can be updated by calling "update" with a new set of props, causing a set of re-renders.
///
/// This is useful when a component tree can be driven by external state (IE SSR) but it would be too expensive
@@ -122,12 +123,12 @@ impl VirtualDom {
/// ```ignore
/// // Directly from a closure
///
/// let dom = VirtualDom::new(|ctx| ctx.render(rsx!{ div {"hello world"} }));
/// let dom = VirtualDom::new(|cx| cx.render(rsx!{ div {"hello world"} }));
///
/// // or pass in...
///
/// let root = |ctx| {
/// ctx.render(rsx!{
/// let root = |cx| {
/// cx.render(rsx!{
/// div {"hello world"}
/// })
/// }
@@ -135,8 +136,8 @@ impl VirtualDom {
///
/// // or directly from a fn
///
/// fn Example(ctx: Context, props: &SomeProps) -> VNode {
/// ctx.render(rsx!{ div{"hello world"} })
/// fn Example(cx: Context, props: &SomeProps) -> VNode {
/// cx.render(rsx!{ div{"hello world"} })
/// }
///
/// let dom = VirtualDom::new(Example);
@@ -395,11 +396,13 @@ pub struct Scope {
// Stores references into the listeners attached to the vnodes
// NEEDS TO BE PRIVATE
pub(crate) listeners: RefCell<Vec<(*const Cell<RealDomNode>, *const dyn Fn(VirtualEvent))>>,
pub(crate) suspended_tasks: Vec<Box<dyn Future<Output = VNode<'static>>>>,
// pub(crate) listeners: RefCell<nohash_hasher::IntMap<u32, *const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// NoHashMap<RealDomNode, <*const dyn Fn(VirtualEvent)>
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>
}
// We need to pin the hook so it doesn't move as we initialize the list of hooks
@@ -465,6 +468,7 @@ impl Scope {
listeners: Default::default(),
hookidx: Default::default(),
descendents: Default::default(),
suspended_tasks: Default::default(),
}
}
@@ -588,9 +592,9 @@ impl Scope {
///
/// }
///
/// fn example(ctx: Context, props: &Props -> VNode {
/// fn example(cx: Context, props: &Props -> VNode {
/// html! {
/// <div> "Hello, {ctx.ctx.name}" </div>
/// <div> "Hello, {cx.cx.name}" </div>
/// }
/// }
/// ```
@@ -645,6 +649,14 @@ pub trait Scoped<'src>: Sized {
self.get_scope().event_channel.clone()
}
fn schedule_effect(&self) -> Rc<dyn Fn() + 'static> {
todo!()
}
fn schedule_layout_effect(&self) {
todo!()
}
/// Take a lazy VNode structure and actually build it with the context of the VDom's efficient VNode allocator.
///
/// This function consumes the context and absorb the lifetime, so these VNodes *must* be returned.
@@ -652,12 +664,12 @@ pub trait Scoped<'src>: Sized {
/// ## Example
///
/// ```ignore
/// fn Component(ctx: Context<()>) -> VNode {
/// fn Component(cx: Context<()>) -> VNode {
/// // Lazy assemble the VNode tree
/// let lazy_tree = html! {<div> "Hello World" </div>};
///
/// // Actually build the tree and allocate it
/// ctx.render(lazy_tree)
/// cx.render(lazy_tree)
/// }
///```
fn render<'a, F: for<'b> FnOnce(&'b NodeCtx<'src>) -> VNode<'src> + 'src + 'a>(
@@ -750,7 +762,7 @@ Any function prefixed with "use" should not be called conditionally.
///
fn use_create_context<T: 'static>(&self, init: impl Fn() -> T) {
let scope = self.get_scope();
let mut ctxs = scope.shared_contexts.borrow_mut();
let mut cxs = scope.shared_contexts.borrow_mut();
let ty = TypeId::of::<T>();
let is_initialized = self.use_hook(
@@ -763,14 +775,14 @@ Any function prefixed with "use" should not be called conditionally.
|_| {},
);
match (is_initialized, ctxs.contains_key(&ty)) {
match (is_initialized, cxs.contains_key(&ty)) {
// Do nothing, already initialized and already exists
(true, true) => {}
// Needs to be initialized
(false, false) => {
log::debug!("Initializing context...");
ctxs.insert(ty, Rc::new(init()));
cxs.insert(ty, Rc::new(init()));
}
_ => debug_assert!(false, "Cannot initialize two contexts of the same type"),
@@ -810,9 +822,9 @@ Any function prefixed with "use" should not be called conditionally.
log::debug!("Searching {:#?} for valid shared_context", inner.arena_idx);
let shared_contexts = inner.shared_contexts.borrow();
if let Some(shared_ctx) = shared_contexts.get(&ty) {
log::debug!("found matching ctx");
let rc = shared_ctx
if let Some(shared_cx) = shared_contexts.get(&ty) {
log::debug!("found matching cx");
let rc = shared_cx
.clone()
.downcast::<T>()
.expect("Should not fail, already validated the type from the hashmap");
@@ -841,10 +853,32 @@ Any function prefixed with "use" should not be called conditionally.
)
}
fn suspend<O>(
fn suspend<O: 'src>(
&self,
f: impl Future<Output = O>,
g: impl FnOnce(O) -> VNode<'src> + 'src,
f: &'src mut Pin<Box<dyn Future<Output = O> + Send + 'static>>,
g: impl FnOnce(SuspendedContext, O) -> VNode<'src> + 'src,
) -> VNode<'src> {
match f.now_or_never() {
Some(o) => {
let suspended_cx = SuspendedContext {};
let nodes = g(suspended_cx, o);
return nodes;
}
None => {
// we need to register this task
VNode::Suspended
}
}
}
}
#[derive(Clone)]
pub struct SuspendedContext {}
impl SuspendedContext {
pub fn render<'a, 'src, F: for<'b> FnOnce(&'b NodeCtx<'src>) -> VNode<'src> + 'src + 'a>(
self,
lazy_nodes: LazyNodes<'src, F>,
) -> VNode<'src> {
todo!()
}
+2 -2
View File
@@ -1,7 +1,7 @@
use dioxus_ssr::prelude::*;
pub static Blog: FC<()> = |ctx| {
rsx! { in ctx,
pub static Blog: FC<()> = |cx| {
rsx! { in cx,
div {
}
+2 -2
View File
@@ -1,7 +1,7 @@
use dioxus_ssr::prelude::*;
pub static Community: FC<()> = |ctx| {
rsx! { in ctx,
pub static Community: FC<()> = |cx| {
rsx! { in cx,
div {
}
+2 -2
View File
@@ -1,7 +1,7 @@
use dioxus_ssr::prelude::*;
pub static Docs: FC<()> = |ctx| {
rsx! { in ctx,
pub static Docs: FC<()> = |cx| {
rsx! { in cx,
div {
}
+3 -3
View File
@@ -11,7 +11,7 @@ const HeroContent: [(&'static str, &'static str); 3] = [
const SnippetHighlights: &'static str = include_str!("./../snippets.md");
pub static Home: FC<()> = |ctx| {
pub static Home: FC<()> = |cx| {
let hero = HeroContent.iter().map(|(title, body)| {
rsx! {
div {
@@ -20,9 +20,9 @@ pub static Home: FC<()> = |ctx| {
}
}
});
let snippets: Vec<VNode> = crate::utils::markdown_to_snippet(ctx, SnippetHighlights);
let snippets: Vec<VNode> = crate::utils::markdown_to_snippet(cx, SnippetHighlights);
rsx! { in ctx,
rsx! { in cx,
div {
header {
// Hero
+2 -2
View File
@@ -1,7 +1,7 @@
use dioxus_ssr::prelude::*;
pub static Tutorial: FC<()> = |ctx| {
rsx! { in ctx,
pub static Tutorial: FC<()> = |cx| {
rsx! { in cx,
div {
}
+14 -14
View File
@@ -24,18 +24,18 @@ fn main() {
*/
}
static App: FC<()> = |ctx| {
let (url, set_url) = use_state(&ctx, || "");
static App: FC<()> = |cx| {
let (url, set_url) = use_state(&cx, || "");
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 {}),
"community" => rsx!(in cx, Community {}),
"tutorial" => rsx!(in cx, Tutorial {}),
"blog" => rsx!(in cx, Blog {}),
"docs" => rsx!(in cx, Docs {}),
_ => rsx!(in cx, Home {}),
};
ctx.render(rsx! {
cx.render(rsx! {
div {
NavBar {}
{body}
@@ -44,8 +44,8 @@ static App: FC<()> = |ctx| {
})
};
static NavBar: FC<()> = |ctx| {
ctx.render(rsx! {
static NavBar: FC<()> = |cx| {
cx.render(rsx! {
header {
a {
href: "/"
@@ -99,7 +99,7 @@ static SECTIONS: &[(&str, &[(&str, &str)])] = &[
),
];
fn Footer(ctx: Context<()>) -> VNode {
fn Footer(cx: Context<()>) -> VNode {
let sections = SECTIONS.iter().map(|(section, raw_links)| {
let links = raw_links.iter().map(|(link_name, href)| {
rsx! (
@@ -117,7 +117,7 @@ fn Footer(ctx: Context<()>) -> VNode {
}
});
ctx.render(rsx! {
cx.render(rsx! {
footer {
div {
div {
@@ -136,8 +136,8 @@ fn Footer(ctx: Context<()>) -> VNode {
})
}
const ExternalLinkIcon: FC<()> = |ctx| {
ctx.render(html! {
const ExternalLinkIcon: FC<()> = |cx| {
cx.render(html! {
<svg x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15">
<path
fill="currentColor"
+8 -8
View File
@@ -4,9 +4,9 @@
#[derive(PartialEq, Properties)]
struct Props { name: &'static str }
static HelloMessage: FC<Props> = |ctx| {
ctx.render(rsx!{
div { "Hello {ctx.props.name}" }
static HelloMessage: FC<Props> = |cx| {
cx.render(rsx!{
div { "Hello {cx.props.name}" }
})
}
```
@@ -16,8 +16,8 @@ static HelloMessage: FC<Props> = |ctx| {
Choose from a close-to-html syntax or the standard rsx! syntax
```rust
static HelloMessage: FC<()> = |ctx| {
ctx.render(html!{
static HelloMessage: FC<()> = |cx| {
cx.render(html!{
<div> Hello World! </div>
})
}
@@ -33,8 +33,8 @@ enum LightState {
Yellow,
Red,
}
static HelloMessage: FC<()> = |ctx| {
let (color, set_color) = use_state(&ctx, || LightState::Green);
static HelloMessage: FC<()> = |cx| {
let (color, set_color) = use_state(&cx, || LightState::Green);
let title = match color {
Green => "Green means go",
@@ -42,7 +42,7 @@ static HelloMessage: FC<()> = |ctx| {
Red => "Red means stop",
};
ctx.render(rsx!{
cx.render(rsx!{
h1 { "{title}" }
button { "tick"
onclick: move |_| set_color(match color {
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus_ssr::prelude::{Context, VNode};
// Parse a snippet into
pub fn markdown_to_snippet<'a, P>(ctx: Context<'a, P>, text: &str) -> Vec<VNode<'a>> {
pub fn markdown_to_snippet<'a, P>(cx: Context<'a, P>, text: &str) -> Vec<VNode<'a>> {
let snips = Vec::new();
use pulldown_cmark::{Options, Parser};
let mut options = Options::empty();
+3 -5
View File
@@ -1,5 +1,3 @@
fn main() {
// let mut s = Context { props: &() };
// let g = Component(&mut s);
@@ -15,9 +13,9 @@ fn main() {
// Remvoe,
// }
// static Component: FC<()> = |ctx| {
// static Component: FC<()> = |cx| {
// let (tasks, dispatch) = use_reducer(
// ctx,
// cx,
// || CompState { tasks: Vec::new() },
// |state, action: Actions| match action {
// Actions::Add => state,
@@ -48,7 +46,7 @@ fn main() {
// };
// fn use_reducer<Props, State, Action>(
// ctx: &mut Context<Props>,
// cx: &mut Context<Props>,
// init: fn() -> State,
// reducer: fn(State, Action) -> State,
// ) -> (State, impl Fn(Action)) {
+6 -6
View File
@@ -20,7 +20,7 @@ This is moderately efficient because the fields of the map are moved, but the da
However, if you used similar approach with Dioxus:
```rust
let (map, set_map) = use_state(&ctx, || HashMap::new());
let (map, set_map) = use_state(&cx, || HashMap::new());
set_map({
let mut newmap = map.clone();
newmap.set(key, value);
@@ -40,11 +40,11 @@ uses the same memoization on top of the use_context API.
Here's a fully-functional todo app using the use_map API:
```rust
static TodoList: FC<()> = |ctx| {
let todos = use_map(ctx, || HashMap::new());
static TodoList: FC<()> = |cx| {
let todos = use_map(cx, || HashMap::new());
let input = use_ref(|| None);
ctx.render(rsx!{
cx.render(rsx!{
div {
button {
"Add todo"
@@ -84,10 +84,10 @@ fn use_map() {}
// Elements are received as Rc<T> in case the underlying collection is shuffled around
// Setters/getters can be generated
fn use_collection<'a, T: Collection>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
f: impl Fn() -> T,
) -> CollectionHandle<'a, T> {
ctx.use_hook(
cx.use_hook(
|| {},
|h| {
//
+9 -9
View File
@@ -27,13 +27,13 @@ mod client {
Ok(dioxus_web::WebsysRenderer::start(APP).await)
}
static APP: FC<()> = |ctx| {
static APP: FC<()> = |cx| {
todo!()
// let (selected_stream, set_stream) = use_state(&ctx, || SelectedStream::Football);
// let (selected_stream, set_stream) = use_state(&cx, || SelectedStream::Football);
// let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });
// ctx.render(rsx! {
// cx.render(rsx! {
// div {
// h1 { "Tide basic CRUD app" }
// h2 { "Chosen stream: {selected_stream}" }
@@ -102,27 +102,27 @@ mod server {
selected_stream: SelectedStream,
}
static STREAM_LIST: FC<SreamListProps> = |ctx| {
static STREAM_LIST: FC<SreamListProps> = |cx| {
//
let g = match ctx.selected_stream {
SelectedStream::Football => ctx.render(rsx! {
let g = match cx.selected_stream {
SelectedStream::Football => cx.render(rsx! {
li {
"watch football!"
}
}),
SelectedStream::Hockey => ctx.render(rsx! {
SelectedStream::Hockey => cx.render(rsx! {
li {
"watch football!"
}
}),
SelectedStream::Socker => ctx.render(rsx! {
SelectedStream::Socker => cx.render(rsx! {
li {
"watch football!"
}
}),
};
ctx.render(rsx! {
cx.render(rsx! {
div {
}
+17 -17
View File
@@ -27,13 +27,13 @@ mod client {
Ok(dioxus_web::WebsysRenderer::start(APP).await)
}
static APP: FC<()> = |ctx| {
static APP: FC<()> = |cx| {
todo!()
// let (selected_stream, set_stream) = use_state(&ctx, || SelectedStream::Football);
// let (selected_stream, set_stream) = use_state(&cx, || SelectedStream::Football);
// let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });
// ctx.render(rsx! {
// cx.render(rsx! {
// div {
// h1 { "Tide basic CRUD app" }
// h2 { "Chosen stream: {selected_stream}" }
@@ -102,29 +102,29 @@ mod server {
selected_stream: SelectedStream,
}
static STREAM_LIST: FC<SreamListProps> = |ctx| {
static STREAM_LIST: FC<SreamListProps> = |cx| {
//
match ctx.selected_stream {
SelectedStream::Football => ctx.render(rsx! {
match cx.selected_stream {
SelectedStream::Football => cx.render(rsx! {
li {
"watch football!"
}
}),
_ => unimplemented!()
// .render(ctx),
// .render(cx),
// SelectedStream::Hockey => rsx! {
// li {
// "watch football!"
// }
// }
// .render(ctx),
// .render(cx),
// SelectedStream::Socker => rsx! {
// li {
// "watch football!"
// }
// }
// .render(ctx),
// .render(cx),
}
};
}
@@ -145,21 +145,21 @@ mod ergorsx {
// }
// trait Renderable {
// fn render(self, nodectx: &Ncx) -> VVNode;
// fn render(self, nodecx: &Ncx) -> VVNode;
// }
// impl<F: Fn(&Ncx) -> VVNode> Renderable for DTree<F> {
// fn render(self, nodectx: &Ncx) -> VVNode {
// (self.caller)(nodectx)
// fn render(self, nodecx: &Ncx) -> VVNode {
// (self.caller)(nodecx)
// }
// }
// fn test() {
// let t = 123;
// let r = match t {
// 123 => DTree::new(|f| VVNode {}).render(ctx),
// 456 => DTree::new(|f| VVNode {}).render(ctx),
// 789 => DTree::new(|f| VVNode {}).render(ctx),
// 123 => DTree::new(|f| VVNode {}).render(cx),
// 456 => DTree::new(|f| VVNode {}).render(cx),
// 789 => DTree::new(|f| VVNode {}).render(cx),
// _ => unreachable!(),
// };
// }
@@ -169,11 +169,11 @@ mod ergorsx {
// div {
// }
// }.render(ctx)
// }.render(cx)
// }
// fn example() {
// ctx.render(rsx!{
// cx.render(rsx!{
// div {
// }
+3 -3
View File
@@ -9,11 +9,11 @@ Using the router should feel similar to tide's routing framework where an "addre
Here's an example of how to use the router hook:
```rust
static App: FC<()> = |ctx| {
static App: FC<()> = |cx| {
// Route returns the associated VNodes
// This hook re-fires when the route changes
let route = use_router(ctx, |router| {
let route = use_router(cx, |router| {
router.at("/").get(|path| {
rsx!{ <LandingPage /> }
});
@@ -27,7 +27,7 @@ static App: FC<()> = |ctx| {
});
});
ctx.render(rsx!{
cx.render(rsx!{
div {
Navbar {}
{route}
+3 -3
View File
@@ -14,8 +14,8 @@ struct ExampleProps {
initial_name: String,
}
static Example: FC<ExampleProps> = |ctx| {
let dispaly_name = use_state_new(&ctx, move || ctx.initial_name.clone());
static Example: FC<ExampleProps> = |cx| {
let dispaly_name = use_state_new(&cx, move || cx.initial_name.clone());
let buttons = ["Jack", "Jill", "Bob"].iter().map(|name| {
rsx!{
@@ -27,7 +27,7 @@ static Example: FC<ExampleProps> = |ctx| {
}
});
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "py-12 px-4 text-center w-full max-w-2xl mx-auto",
// classes: [Some("asd")]
+2 -2
View File
@@ -53,11 +53,11 @@ fn html_render(
#[test]
fn test_serialize() {
let mut dom = VirtualDom::new(|ctx| {
let mut dom = VirtualDom::new(|cx| {
//
//
//
ctx.render(rsx! {
cx.render(rsx! {
div {
title: "About W3Schools"
{(0..20).map(|f| rsx!{
+8 -8
View File
@@ -13,8 +13,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
ctx.render(rsx! {
static App: FC<()> = |cx| {
cx.render(rsx! {
div {
h1 {"hello"}
C1 {}
@@ -23,23 +23,23 @@ static App: FC<()> = |ctx| {
})
};
static C1: FC<()> = |ctx| {
ctx.render(rsx! {
static C1: FC<()> = |cx| {
cx.render(rsx! {
button {
"numba 1"
}
})
};
static C2: FC<()> = |ctx| {
ctx.render(rsx! {
static C2: FC<()> = |cx| {
cx.render(rsx! {
button {
"numba 2"
}
})
};
static DocExamples: FC<()> = |ctx| {
static DocExamples: FC<()> = |cx| {
//
let is_ready = false;
@@ -61,7 +61,7 @@ static DocExamples: FC<()> = |ctx| {
// }
// }
ctx.render(rsx! {
cx.render(rsx! {
div {
{ is_ready.then(|| rsx!{ h1 {"We are ready!"} }) }
}
+5 -5
View File
@@ -12,8 +12,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
ctx.render(rsx! {
static App: FC<()> = |cx| {
cx.render(rsx! {
Calcier {
h2 {"abc 1"}
h2 {"abc 2"}
@@ -24,13 +24,13 @@ static App: FC<()> = |ctx| {
})
};
static Calcier: FC<()> = |ctx| {
ctx.render(rsx! {
static Calcier: FC<()> = |cx| {
cx.render(rsx! {
div {
h1 {
"abc 0"
}
{ctx.children()}
{cx.children()}
}
})
};
+7 -7
View File
@@ -24,10 +24,10 @@ fn main() {
#[derive(Debug)]
struct CustomContext([&'static str; 3]);
static Example: FC<()> = |ctx| {
ctx.use_create_context(|| CustomContext(["Jack", "Jill", "Bob"]));
static Example: FC<()> = |cx| {
cx.use_create_context(|| CustomContext(["Jack", "Jill", "Bob"]));
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
span {
@@ -51,11 +51,11 @@ struct ButtonProps {
id: u8,
}
fn CustomButton(ctx: Context<ButtonProps>) -> VNode {
let names = ctx.use_context::<CustomContext>();
let name = names.0[ctx.id as usize];
fn CustomButton(cx: Context<ButtonProps>) -> VNode {
let names = cx.use_context::<CustomContext>();
let name = names.0[cx.id as usize];
ctx.render(rsx!{
cx.render(rsx!{
button {
class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
"{name}"
+10 -10
View File
@@ -10,10 +10,10 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(CustomA))
}
fn CustomA(ctx: Context<()>) -> VNode {
let (val, set_val) = use_state(&ctx, || "abcdef".to_string() as String);
fn CustomA(cx: Context<()>) -> VNode {
let (val, set_val) = use_state(&cx, || "abcdef".to_string() as String);
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "m-8"
"CustomA {val}"
@@ -42,12 +42,12 @@ mod components {
val: String,
}
pub fn CustomB(ctx: Context<PropsB>) -> VNode {
let (first, last) = ctx.val.split_at(3);
ctx.render(rsx! {
pub fn CustomB(cx: Context<PropsB>) -> VNode {
let (first, last) = cx.val.split_at(3);
cx.render(rsx! {
div {
class: "m-8"
"CustomB {ctx.val}"
"CustomB {cx.val}"
CustomC {
val: first.to_string()
}
@@ -63,11 +63,11 @@ mod components {
val: String,
}
fn CustomC(ctx: Context<PropsC>) -> VNode {
ctx.render(rsx! {
fn CustomC(cx: Context<PropsC>) -> VNode {
cx.render(rsx! {
div {
class: "m-8"
"CustomC {ctx.val}"
"CustomC {cx.val}"
}
})
}
+6 -6
View File
@@ -7,8 +7,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App))
}
fn App(ctx: Context<()>) -> VNode {
ctx.render(rsx! {
fn App(cx: Context<()>) -> VNode {
cx.render(rsx! {
main { class: "dark:bg-gray-800 bg-white relative h-screen"
NavBar {}
{(0..10).map(|f| rsx!(Landing { key: "{f}" }))}
@@ -16,8 +16,8 @@ fn App(ctx: Context<()>) -> VNode {
})
}
fn NavBar(ctx: Context<()>) -> VNode {
ctx.render(rsx!{
fn NavBar(cx: Context<()>) -> VNode {
cx.render(rsx!{
header { class: "h-24 sm:h-32 flex items-center z-30 w-full"
div { class: "container mx-auto px-6 flex items-center justify-between"
div { class: "uppercase text-gray-800 dark:text-white font-black text-3xl"
@@ -56,8 +56,8 @@ fn NavBar(ctx: Context<()>) -> VNode {
})
}
fn Landing(ctx: Context<()>) -> VNode {
ctx.render(rsx!{
fn Landing(cx: Context<()>) -> VNode {
cx.render(rsx!{
div { class: "bg-white dark:bg-gray-800 flex relative z-20 items-center"
div { class: "container mx-auto px-6 flex flex-col justify-between items-center relative py-8"
div { class: "flex flex-col"
+5 -5
View File
@@ -8,9 +8,9 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
fn App(ctx: Context<()>) -> VNode {
let cansee = use_state_new(&ctx, || false);
rsx! { in ctx,
fn App(cx: Context<()>) -> VNode {
let cansee = use_state_new(&cx, || false);
rsx! { in cx,
div {
"Shadow of the child:"
button { onclick: move |_| cansee.set(!**cansee)
@@ -21,8 +21,8 @@ fn App(ctx: Context<()>) -> VNode {
}
}
fn Child(ctx: Context<()>) -> VNode {
rsx! { in ctx,
fn Child(cx: Context<()>) -> VNode {
rsx! { in cx,
section { class: "py-6 bg-coolGray-100 text-coolGray-900"
div { class: "container mx-auto flex flex-col items-center justify-center p-4 space-y-8 md:p-10 md:px-24 xl:px-48"
h1 { class: "text-5xl font-bold leading-none text-center",
+2 -2
View File
@@ -12,8 +12,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
ctx.render(rsx! {
static App: FC<()> = |cx| {
cx.render(rsx! {
h2 { "abc 1" }
div {
"hello world!"
+2 -2
View File
@@ -10,9 +10,9 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
}
static Example: FC<()> = |ctx| {
static Example: FC<()> = |cx| {
let nodes = (0..15).map(|f| rsx! (li { key: "{f}", "{f}"}));
ctx.render(rsx! {
cx.render(rsx! {
div {
span {
class: "px-2 py-1 flex w-36 mt-4 items-center text-xs rounded-md font-semibold text-yellow-500 bg-yellow-100"
+2 -2
View File
@@ -5,8 +5,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(App))
}
fn App(ctx: Context<()>) -> VNode {
ctx.render(rsx! {
fn App(cx: Context<()>) -> VNode {
cx.render(rsx! {
div { "Hello, world!" }
})
}
+6 -6
View File
@@ -12,8 +12,8 @@ fn main() {
}
// this is a component
static Example: FC<()> = |ctx| {
let (event, set_event) = use_state(&ctx, || None);
static Example: FC<()> = |cx| {
let (event, set_event) = use_state(&cx, || None);
let handler = move |evt| {
set_event(Some(evt));
@@ -21,7 +21,7 @@ static Example: FC<()> = |ctx| {
log::info!("hello world");
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "py-12 px-4 w-full max-w-2xl mx-auto bg-red-100"
@@ -48,10 +48,10 @@ struct ExampleProps {
name: String,
}
static Example2: FC<ExampleProps> = |ctx| {
ctx.render(rsx! {
static Example2: FC<ExampleProps> = |cx| {
cx.render(rsx! {
div {
h1 {"hello {ctx.name}"}
h1 {"hello {cx.name}"}
}
})
};
+8 -8
View File
@@ -10,10 +10,10 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
let (val, set_val) = use_state(&ctx, || "asd".to_string());
static App: FC<()> = |cx| {
let (val, set_val) = use_state(&cx, || "asd".to_string());
ctx.render(rsx! {
cx.render(rsx! {
div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl"
div { class: "container py-5 max-w-md mx-auto"
h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl",
@@ -35,8 +35,8 @@ static App: FC<()> = |ctx| {
})
};
static Example: FC<()> = |ctx| {
ctx.render(rsx! {
static Example: FC<()> = |cx| {
cx.render(rsx! {
div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl"
div { class: "container py-5 max-w-md mx-auto"
h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl",
@@ -48,10 +48,10 @@ static Example: FC<()> = |ctx| {
})
};
static UserInput: FC<()> = |ctx| {
let (val, set_val) = use_state(&ctx, || "asd".to_string());
static UserInput: FC<()> = |cx| {
let (val, set_val) = use_state(&cx, || "asd".to_string());
rsx! { in ctx,
rsx! { in cx,
div { class: "mb-4"
input { class: "shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
placeholder: "Username"
+3 -3
View File
@@ -9,12 +9,12 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example))
}
static Example: FC<()> = |ctx| {
let (name, set_name) = use_state(&ctx, || "...?");
static Example: FC<()> = |cx| {
let (name, set_name) = use_state(&cx, || "...?");
log::debug!("Running component....");
ctx.render(html! {
cx.render(html! {
<div>
<section class="py-12 px-4 text-center">
<div class="w-full max-w-2xl mx-auto">
+3 -3
View File
@@ -12,10 +12,10 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
let (contents, set_contents) = use_state(&ctx, || "asd");
static App: FC<()> = |cx| {
let (contents, set_contents) = use_state(&cx, || "asd");
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "flex items-center justify-center flex-col"
div {
+3 -3
View File
@@ -13,10 +13,10 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |ctx| {
let (contents, set_contents) = use_state(&ctx, || "asd");
static App: FC<()> = |cx| {
let (contents, set_contents) = use_state(&cx, || "asd");
ctx.render(rsx! {
cx.render(rsx! {
div { class: "flex items-center justify-center flex-col"
div { class: "flex items-center justify-center"
div { class: "flex flex-col bg-white rounded p-4 w-full max-w-xs"
+9 -9
View File
@@ -25,11 +25,11 @@ pub struct TodoItem {
pub contents: String,
}
static App: FC<()> = |ctx| {
let (draft, set_draft) = use_state(&ctx, || "".to_string());
let (filter, set_filter) = use_state(&ctx, || FilterState::All);
let todos = use_state_new(&ctx, || BTreeMap::<uuid::Uuid, TodoItem>::new());
ctx.render(rsx!(
static App: FC<()> = |cx| {
let (draft, set_draft) = use_state(&cx, || "".to_string());
let (filter, set_filter) = use_state(&cx, || FilterState::All);
let todos = use_state_new(&cx, || BTreeMap::<uuid::Uuid, TodoItem>::new());
cx.render(rsx!(
div {
id: "app"
div {
@@ -131,9 +131,9 @@ static App: FC<()> = |ctx| {
))
};
pub fn FilterToggles(ctx: Context<()>) -> VNode {
// let reducer = recoil::use_callback(&ctx, || ());
// let items_left = recoil::use_atom_family(&ctx, &TODOS, uuid::Uuid::new_v4());
pub fn FilterToggles(cx: Context<()>) -> VNode {
// let reducer = recoil::use_callback(&cx, || ());
// let items_left = recoil::use_atom_family(&cx, &TODOS, uuid::Uuid::new_v4());
let toggles = [
("All", "", FilterState::All),
@@ -158,7 +158,7 @@ pub fn FilterToggles(ctx: Context<()>) -> VNode {
let item_text = "";
let items_left = "";
ctx.render(rsx! {
cx.render(rsx! {
footer {
span {
strong {"{items_left}"}
+2 -2
View File
@@ -10,8 +10,8 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
}
static Example: FC<()> = |ctx| {
ctx.render(rsx! {
static Example: FC<()> = |cx| {
cx.render(rsx! {
div {
span {
class: "px-2 py-1 flex w-36 mt-4 items-center text-xs rounded-md font-semibold text-yellow-500 bg-yellow-100"
+3 -3
View File
@@ -5,10 +5,10 @@
// wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
// }
// fn Example(ctx: Context, props: ()) -> VNode {
// let user_data = use_sql_query(&ctx, USER_DATA_QUERY);
// fn Example(cx: Context, props: ()) -> VNode {
// let user_data = use_sql_query(&cx, USER_DATA_QUERY);
// ctx.render(rsx! {
// cx.render(rsx! {
// h1 { "Hello, {username}"}
// button {
// "Delete user"
+10 -10
View File
@@ -25,10 +25,10 @@ struct ExampleProps {
initial_name: &'static str,
}
static Example: FC<ExampleProps> = |ctx| {
let name = use_state_new(&ctx, move || ctx.initial_name);
static Example: FC<ExampleProps> = |cx| {
let name = use_state_new(&cx, move || cx.initial_name);
ctx.render(rsx! {
cx.render(rsx! {
div {
class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
span {
@@ -55,12 +55,12 @@ struct ButtonProps<'src, F: Fn(Rc<dyn MouseEvent>)> {
handler: F,
}
fn CustomButton<'a, F: Fn(MouseEvent)>(ctx: Context<'a, ButtonProps<'a, F>>) -> VNode {
ctx.render(rsx!{
fn CustomButton<'a, F: Fn(MouseEvent)>(cx: Context<'a, ButtonProps<'a, F>>) -> VNode {
cx.render(rsx!{
button {
class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
onmouseover: {&ctx.handler}
"{ctx.name}"
onmouseover: {&cx.handler}
"{cx.name}"
}
})
}
@@ -75,10 +75,10 @@ impl<F: Fn(MouseEvent)> PartialEq for ButtonProps<'_, F> {
struct PlaceholderProps {
val: &'static str,
}
fn Placeholder(ctx: Context<PlaceholderProps>) -> VNode {
ctx.render(rsx! {
fn Placeholder(cx: Context<PlaceholderProps>) -> VNode {
cx.render(rsx! {
div {
"child: {ctx.val}"
"child: {cx.val}"
}
})
}
@@ -2,9 +2,9 @@ use crate::recoil;
use crate::state::{FilterState, TODOS};
use dioxus_core::prelude::*;
pub fn FilterToggles(ctx: Context<()>) -> VNode {
let reducer = recoil::use_callback(&ctx, || ());
let items_left = recoil::use_atom_family(&ctx, &TODOS, uuid::Uuid::new_v4());
pub fn FilterToggles(cx: Context<()>) -> VNode {
let reducer = recoil::use_callback(&cx, || ());
let items_left = recoil::use_atom_family(&cx, &TODOS, uuid::Uuid::new_v4());
let toggles = [
("All", "", FilterState::All),
@@ -27,7 +27,7 @@ pub fn FilterToggles(ctx: Context<()>) -> VNode {
let item_text = "";
let items_left = "";
ctx.render(rsx! {
cx.render(rsx! {
footer {
span {
strong {"{items_left}"}
+2 -2
View File
@@ -10,8 +10,8 @@ use dioxus_web::{prelude::*, WebsysRenderer};
static APP_STYLE: &'static str = include_str!("./style.css");
fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|ctx| {
ctx.render(rsx! {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx| {
cx.render(rsx! {
div {
id: "app"
// style { "{APP_STYLE}" }
+2 -2
View File
@@ -33,10 +33,10 @@ impl RecoilContext<()> {
// let (set, get) = (self.set, self.get);
// TOODS
// .get(&ctx)
// .get(&cx)
// .iter()
// .filter(|(k, v)| v.checked)
// .map(|(k, v)| TODOS.remove(&ctx, k));
// .map(|(k, v)| TODOS.remove(&cx, k));
}
pub fn set_filter(&self, filter: &FilterState) {}
+4 -4
View File
@@ -7,11 +7,11 @@ pub struct TodoEntryProps {
id: uuid::Uuid,
}
pub fn TodoEntry(ctx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state(&ctx, || false);
let todo = use_atom_family(&ctx, &TODOS, ctx.id);
pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state(&cx, || false);
let todo = use_atom_family(&cx, &TODOS, cx.id);
ctx.render(rsx! (
cx.render(rsx! (
li {
"{todo.id}"
input {
+5 -5
View File
@@ -6,12 +6,12 @@ use crate::{
};
use dioxus_core::prelude::*;
pub fn TodoList(ctx: Context<()>) -> VNode {
let (draft, set_draft) = use_state(&ctx, || "".to_string());
let (todos, _) = use_state(&ctx, || Vec::<TodoItem>::new());
let filter = use_atom(&ctx, &FILTER);
pub fn TodoList(cx: Context<()>) -> VNode {
let (draft, set_draft) = use_state(&cx, || "".to_string());
let (todos, _) = use_state(&cx, || Vec::<TodoItem>::new());
let filter = use_atom(&cx, &FILTER);
ctx.render(rsx! {
cx.render(rsx! {
div {
header {
class: "header"
+12 -12
View File
@@ -27,8 +27,8 @@ pub struct TodoItem {
// =======================
// Components
// =======================
pub fn App(ctx: Context<()>) -> VNode {
ctx.render(rsx! {
pub fn App(cx: Context<()>) -> VNode {
cx.render(rsx! {
div {
id: "app"
@@ -52,12 +52,12 @@ pub fn App(ctx: Context<()>) -> VNode {
})
}
pub fn TodoList(ctx: Context<()>) -> VNode {
let (draft, set_draft) = use_state(&ctx, || "".to_string());
let (todos, set_todos) = use_state(&ctx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new());
let (filter, set_filter) = use_state(&ctx, || FilterState::All);
pub fn TodoList(cx: Context<()>) -> VNode {
let (draft, set_draft) = use_state(&cx, || "".to_string());
let (todos, set_todos) = use_state(&cx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new());
let (filter, set_filter) = use_state(&cx, || FilterState::All);
ctx.render(rsx! {
cx.render(rsx! {
div {
header {
class: "header"
@@ -101,8 +101,8 @@ pub struct TodoEntryProps {
item: Rc<TodoItem>,
}
pub fn TodoEntry(ctx: Context<TodoEntryProps>) -> VNode {
let (is_editing, set_is_editing) = use_state(&ctx, || false);
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> VNode {
let (is_editing, set_is_editing) = use_state(&cx, || false);
let contents = "";
let todo = TodoItem {
checked: false,
@@ -110,7 +110,7 @@ pub fn TodoEntry(ctx: Context<TodoEntryProps>) -> VNode {
id: uuid::Uuid::new_v4(),
};
ctx.render(rsx! (
cx.render(rsx! (
li {
"{todo.id}"
input {
@@ -127,7 +127,7 @@ pub fn TodoEntry(ctx: Context<TodoEntryProps>) -> VNode {
))
}
pub fn FilterToggles(ctx: Context<()>) -> VNode {
pub fn FilterToggles(cx: Context<()>) -> VNode {
let toggles = [
("All", "", FilterState::All),
("Active", "active", FilterState::Active),
@@ -151,7 +151,7 @@ pub fn FilterToggles(ctx: Context<()>) -> VNode {
let item_text = "";
let items_left = "";
ctx.render(rsx! {
cx.render(rsx! {
footer {
span {
strong {"{items_left}"}
+18 -18
View File
@@ -72,10 +72,10 @@ impl TodoManager {
}
}
pub fn TodoList(ctx: Context<()>) -> VNode {
let draft = use_state_new(&ctx, || "".to_string());
let todos = use_read(&ctx, &TODO_LIST);
let filter = use_read(&ctx, &FILTER);
pub fn TodoList(cx: Context<()>) -> VNode {
let draft = use_state_new(&cx, || "".to_string());
let todos = use_read(&cx, &TODO_LIST);
let filter = use_read(&cx, &FILTER);
let todolist = todos
.values()
@@ -91,7 +91,7 @@ pub fn TodoList(ctx: Context<()>) -> VNode {
})
});
rsx! { in ctx,
rsx! { in cx,
div {
header {
class: "header"
@@ -116,11 +116,11 @@ pub struct TodoEntryProps {
id: Uuid,
}
pub fn TodoEntry(ctx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state(&ctx, || false);
let todo = use_read(&ctx, &TODO_LIST).get(&ctx.id).unwrap();
pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state(&cx, || false);
let todo = use_read(&cx, &TODO_LIST).get(&cx.id).unwrap();
ctx.render(rsx! (
cx.render(rsx! (
li {
"{todo.id}"
input {
@@ -137,9 +137,9 @@ pub fn TodoEntry(ctx: Context, props: &TodoEntryProps) -> VNode {
))
}
pub fn FilterToggles(ctx: Context<()>) -> VNode {
let reducer = TodoManager(use_recoil_api(ctx));
let items_left = use_read(ctx, &TODOS_LEFT);
pub fn FilterToggles(cx: Context<()>) -> VNode {
let reducer = TodoManager(use_recoil_api(cx));
let items_left = use_read(cx, &TODOS_LEFT);
let toggles = [
("All", "", FilterState::All),
@@ -164,7 +164,7 @@ pub fn FilterToggles(ctx: Context<()>) -> VNode {
_ => "items",
};
rsx! { in ctx,
rsx! { in cx,
footer {
span {
strong {"{items_left}"}
@@ -178,8 +178,8 @@ pub fn FilterToggles(ctx: Context<()>) -> VNode {
}
}
pub fn Footer(ctx: Context<()>) -> VNode {
rsx! { in ctx,
pub fn Footer(cx: Context<()>) -> VNode {
rsx! { in cx,
footer { class: "info"
p {"Double-click to edit a todo"}
p {
@@ -196,9 +196,9 @@ pub fn Footer(ctx: Context<()>) -> VNode {
const APP_STYLE: &'static str = include_str!("./todomvc/style.css");
fn App(ctx: Context<()>) -> VNode {
use_init_recoil_root(ctx, |_| {});
rsx! { in ctx,
fn App(cx: Context<()>) -> VNode {
use_init_recoil_root(cx, |_| {});
rsx! { in cx,
div { id: "app"
TodoList {}
Footer {}
+2 -2
View File
@@ -9,8 +9,8 @@ fn main() {
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
console_error_panic_hook::set_once();
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|ctx| {
ctx.render(html! {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx| {
cx.render(html! {
<div>
<div class="flex items-center justify-center flex-col">
<div class="flex items-center justify-center">
+2 -2
View File
@@ -179,9 +179,9 @@ mod tests {
pretty_env_logger::init();
log::info!("Hello!");
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|ctx| {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx| {
todo!()
// ctx.render(html! {
// cx.render(html! {
// <div>
// "Hello world"
// <button onclick={move |_| log::info!("button1 clicked!")}> "click me" </button>
@@ -147,10 +147,10 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
}
fn Component(ctx: Context, props: ()) -> VNode {
let user_data = use_sql_query(&ctx, USER_DATA_QUERY);
fn Component(cx: Context, props: ()) -> VNode {
let user_data = use_sql_query(&cx, USER_DATA_QUERY);
ctx.render(rsx! {
cx.render(rsx! {
h1 { "Hello, {username}"}
button {
"Delete user"
+2 -2
View File
@@ -8,8 +8,8 @@ Dioxus-webview is an attempt at making a simpler "Tauri" where creating desktop
// main.rs
#[async_std::main]
async fn main() {
dioxus_webview::new(|ctx| {
let (count, set_count) = use_state(&ctx, || 0);
dioxus_webview::new(|cx| {
let (count, set_count) = use_state(&cx, || 0);
html! {
<div>
<h1> "Dioxus Desktop Demo" </h1>
+6 -6
View File
@@ -36,22 +36,22 @@ fn blah() {
let handler = dioxus_liveview::new_handler()
.from_directory("abc123") // serve a given directory as the root
.with_context(|| SomeContext {}) // build out a new context for all of the server-rendered components to share
.with_route(SERVER_RENDERED_KEY, |ctx: &ServerRendered| {
.with_route(SERVER_RENDERED_KEY, |cx: &ServerRendered| {
//
})
.with_route(SERVER_RENDERED_KEY, |ctx| {
.with_route(SERVER_RENDERED_KEY, |cx| {
//
})
.with_route(SERVER_RENDERED_KEY, |ctx| {
.with_route(SERVER_RENDERED_KEY, |cx| {
//
})
.with_route(SERVER_RENDERED_KEY, |ctx| {
.with_route(SERVER_RENDERED_KEY, |cx| {
//
})
.with_route(SERVER_RENDERED_KEY, |ctx| {
.with_route(SERVER_RENDERED_KEY, |cx| {
//
})
.with_route(SERVER_RENDERED_KEY, |ctx| {
.with_route(SERVER_RENDERED_KEY, |cx| {
//
})
// depend on the framework, build a different type of handler
+4 -4
View File
@@ -17,8 +17,8 @@ fn main() {
.expect("Webview finished");
}
static Example: FC<()> = |ctx| {
ctx.render(html! {
static Example: FC<()> = |cx| {
cx.render(html! {
<div>
<svg class="octicon octicon-star v-align-text-bottom"
viewBox="0 0 14 16" version="1.1"
@@ -36,8 +36,8 @@ static Example: FC<()> = |ctx| {
</div>
})
};
// static Example: FC<()> = |ctx| {
// ctx.render(rsx! {
// static Example: FC<()> = |cx| {
// cx.render(rsx! {
// div {
// class: "flex items-center justify-center flex-col"
// div {