Feat: overall API updates
This commit is contained in:
1 parent
125f5426a4
commit
f47651b32a
16 files changed
+234
-177
No files matched your search
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"rust-analyzer.inlayHints.enable": true
|
"rust-analyzer.inlayHints.enable": false
|
||||||
}
|
}
|
||||||
+3
-2
@@ -28,8 +28,8 @@
|
|||||||
# Project: Hooks + Context + Subscriptions (TBD)
|
# Project: Hooks + Context + Subscriptions (TBD)
|
||||||
> Implement the foundations for state management
|
> Implement the foundations for state management
|
||||||
- [x] Implement context object
|
- [x] Implement context object
|
||||||
- [ ] Implement use_state
|
- [x] Implement use_state
|
||||||
- [ ] Implement use_ref
|
- [x] Implement use_ref
|
||||||
- [ ] Implement use_reducer
|
- [ ] Implement use_reducer
|
||||||
- [ ] Implement use_context
|
- [ ] Implement use_context
|
||||||
|
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
# Project: Initial VDOM support (TBD)
|
# Project: Initial VDOM support (TBD)
|
||||||
> Get the initial VDom + Event System + Patching + Diffing + Component framework up and running
|
> Get the initial VDom + Event System + Patching + Diffing + Component framework up and running
|
||||||
|
> Get a demo working using just the web
|
||||||
- [x] (Core) Migrate virtual node into new VNode type
|
- [x] (Core) Migrate virtual node into new VNode type
|
||||||
- [x] (Core) Arena allocate VNodes
|
- [x] (Core) Arena allocate VNodes
|
||||||
- [x] (Core) Allow VNodes to borrow arena contents
|
- [x] (Core) Allow VNodes to borrow arena contents
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,6 @@ members = [
|
|||||||
# Built-in
|
# Built-in
|
||||||
"packages/dioxus",
|
"packages/dioxus",
|
||||||
"packages/core",
|
"packages/core",
|
||||||
"packages/hooks",
|
|
||||||
"packages/recoil",
|
"packages/recoil",
|
||||||
"packages/redux",
|
"packages/redux",
|
||||||
"packages/core-macro",
|
"packages/core-macro",
|
||||||
@@ -15,6 +14,7 @@ members = [
|
|||||||
# "packages/macro",
|
# "packages/macro",
|
||||||
# TODO @Jon, share the validation code
|
# TODO @Jon, share the validation code
|
||||||
# "packages/web",
|
# "packages/web",
|
||||||
|
# "packages/hooks",
|
||||||
"packages/cli",
|
"packages/cli",
|
||||||
"examples",
|
"examples",
|
||||||
"packages/html-macro",
|
"packages/html-macro",
|
||||||
|
|||||||
@@ -19,12 +19,10 @@ static Example: FC<Props> = |ctx, props| {
|
|||||||
ctx.view(move |bump| {
|
ctx.view(move |bump| {
|
||||||
button(bump)
|
button(bump)
|
||||||
.on("click", move |_| {
|
.on("click", move |_| {
|
||||||
// //
|
|
||||||
println!("Value is {}", props.name);
|
println!("Value is {}", props.name);
|
||||||
println!("Value is {}", value.as_str());
|
println!("Value is {}", value.as_str());
|
||||||
println!("Value is {}", *value);
|
println!("Value is {}", *value);
|
||||||
})
|
})
|
||||||
//
|
|
||||||
.on("click", move |_| {
|
.on("click", move |_| {
|
||||||
println!("Value is {}", props.name);
|
println!("Value is {}", props.name);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,131 +4,21 @@ use dioxus_core::prelude::*;
|
|||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Our flagship demo :)
|
||||||
|
|
||||||
|
*/
|
||||||
static Example: FC<()> = |ctx, props| {
|
static Example: FC<()> = |ctx, props| {
|
||||||
todo!()
|
let (val1, set_val1) = use_state(&ctx, || "b1");
|
||||||
// let (val1, set_val1) = use_state(&ctx, || "b1");
|
|
||||||
|
|
||||||
// ctx.view(|bump| {
|
ctx.view(html! {
|
||||||
// builder::button(bump)
|
<div>
|
||||||
// .on("click", move |c| {
|
<button onclick={move |_| set_val1("b1")}> "Set value to b1" </button>
|
||||||
// //
|
<button onclick={move |_| set_val1("b2")}> "Set value to b2" </button>
|
||||||
// println!("Value is {}", val1);
|
<button onclick={move |_| set_val1("b3")}> "Set value to b3" </button>
|
||||||
// })
|
<div>
|
||||||
// .finish()
|
<p> "Value is: {val1}" </p>
|
||||||
// })
|
</div>
|
||||||
// ctx.view(html! {
|
</div>
|
||||||
// <div>
|
})
|
||||||
// <button onclick={move |_| set_val1("b1")}> "Set value to b1" </button>
|
|
||||||
// <button onclick={move |_| set_val1("b2")}> "Set value to b2" </button>
|
|
||||||
// <button onclick={move |_| set_val1("b3")}> "Set value to b3" </button>
|
|
||||||
// <div>
|
|
||||||
// <p> "Value is: {val1}" </p>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// })
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use use_state_def::use_state;
|
|
||||||
mod use_state_def {
|
|
||||||
use dioxus_core::prelude::*;
|
|
||||||
use std::{borrow::BorrowMut, cell::RefCell, ops::DerefMut, rc::Rc};
|
|
||||||
|
|
||||||
struct UseState<T: 'static> {
|
|
||||||
new_val: Rc<RefCell<Option<T>>>,
|
|
||||||
current_val: T,
|
|
||||||
caller: Box<dyn Fn(T) + 'static>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Store state between component renders!
|
|
||||||
/// When called, this hook retrives a stored value and provides a setter to update that value.
|
|
||||||
/// When the setter is called, the component is re-ran with the new value.
|
|
||||||
///
|
|
||||||
/// This is behaves almost exactly the same way as React's "use_state".
|
|
||||||
///
|
|
||||||
/// Usage:
|
|
||||||
/// ```ignore
|
|
||||||
/// static Example: FC<()> = |ctx| {
|
|
||||||
/// let (counter, set_counter) = use_state(ctx, || 0);
|
|
||||||
/// let increment = || set_couter(counter + 1);
|
|
||||||
/// let decrement = || set_couter(counter + 1);
|
|
||||||
///
|
|
||||||
/// html! {
|
|
||||||
/// <div>
|
|
||||||
/// <h1>"Counter: {counter}" </h1>
|
|
||||||
/// <button onclick={increment}> "Increment" </button>
|
|
||||||
/// <button onclick={decrement}> "Decrement" </button>
|
|
||||||
/// </div>
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn use_state<'b, 'a, T: 'static, F: FnOnce() -> T + 'static>(
|
|
||||||
ctx: &'b Context<'a>,
|
|
||||||
initial_state_fn: F,
|
|
||||||
) -> (&'a T, &'a impl Fn(T)) {
|
|
||||||
ctx.use_hook(
|
|
||||||
move || UseState {
|
|
||||||
new_val: Rc::new(RefCell::new(None)),
|
|
||||||
current_val: initial_state_fn(),
|
|
||||||
caller: Box::new(|_| println!("setter called!")),
|
|
||||||
},
|
|
||||||
move |hook| {
|
|
||||||
let inner = hook.new_val.clone();
|
|
||||||
let scheduled_update = ctx.schedule_update();
|
|
||||||
|
|
||||||
// get ownership of the new val and replace the current with the new
|
|
||||||
// -> as_ref -> borrow_mut -> deref_mut -> take
|
|
||||||
// -> rc -> &RefCell -> RefMut -> &Option<T> -> T
|
|
||||||
if let Some(new_val) = hook.new_val.as_ref().borrow_mut().deref_mut().take() {
|
|
||||||
hook.current_val = new_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: swap out the caller with a subscription call and an internal update
|
|
||||||
hook.caller = Box::new(move |new_val| {
|
|
||||||
// update the setter with the new value
|
|
||||||
let mut new_inner = inner.as_ref().borrow_mut();
|
|
||||||
*new_inner = Some(new_val);
|
|
||||||
|
|
||||||
// Ensure the component gets updated
|
|
||||||
scheduled_update();
|
|
||||||
});
|
|
||||||
|
|
||||||
// box gets derefed into a ref which is then taken as ref with the hook
|
|
||||||
(&hook.current_val, &hook.caller)
|
|
||||||
},
|
|
||||||
|_| {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod use_ref_def {
|
|
||||||
use dioxus_core::prelude::*;
|
|
||||||
use std::{borrow::BorrowMut, cell::RefCell, ops::DerefMut, rc::Rc};
|
|
||||||
|
|
||||||
pub struct UseRef<T: 'static> {
|
|
||||||
current: RefCell<T>,
|
|
||||||
}
|
|
||||||
impl<T: 'static> UseRef<T> {
|
|
||||||
fn new(val: T) -> Self {
|
|
||||||
Self {
|
|
||||||
current: RefCell::new(val),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn modify(&self, modifier: impl FnOnce(&mut T)) {
|
|
||||||
let mut val = self.current.borrow_mut();
|
|
||||||
let val_as_ref = val.deref_mut();
|
|
||||||
modifier(val_as_ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Store a mutable value between renders!
|
|
||||||
/// To read the value, borrow the ref.
|
|
||||||
/// To change it, use modify.
|
|
||||||
/// Modifications to this value do not cause updates to the component
|
|
||||||
pub fn use_ref<'a, T: 'static>(
|
|
||||||
ctx: &'a Context<'a>,
|
|
||||||
initial_state_fn: impl FnOnce() -> T + 'static,
|
|
||||||
) -> &'a UseRef<T> {
|
|
||||||
ctx.use_hook(|| UseRef::new(initial_state_fn()), |state| &*state, |_| {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#![allow(unused)]
|
||||||
|
//! Example of components in
|
||||||
|
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
|
use dioxus_core::prelude::*;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
static Header: FC<()> = |ctx, props| {
|
||||||
|
let inner = use_ref(&ctx, || 0);
|
||||||
|
|
||||||
|
let handler1 = move || println!("Value is {}", inner.current());
|
||||||
|
|
||||||
|
ctx.view(html! {
|
||||||
|
<div>
|
||||||
|
<h1> "This is the header bar" </h1>
|
||||||
|
<h1> "Idnt it awesome" </h1>
|
||||||
|
<button onclick={move |_| handler1()}> "Click me" </button>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bottom: FC<()> = |ctx, props| {
|
||||||
|
ctx.view(html! {
|
||||||
|
<div>
|
||||||
|
<h1> "bruh 1" </h1>
|
||||||
|
<h1> "bruh 2" </h1>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
static Example: FC<()> = |ctx, props| {
|
||||||
|
ctx.view(html! {
|
||||||
|
<div>
|
||||||
|
<h1> "BROSKI!" </h1>
|
||||||
|
<h1> "DRO!" </h1>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
};
|
||||||
@@ -20,15 +20,20 @@ struct Props {
|
|||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
impl Properties for Props {
|
impl Properties for Props {
|
||||||
fn new() -> Self {
|
fn call(&self, ptr: *const ()) {}
|
||||||
todo!()
|
|
||||||
}
|
// fn new() -> Self {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
static Example: FC<Props> = |ctx, props| {
|
static Example: FC<Props> = |ctx, props| {
|
||||||
ctx.view(html! {
|
ctx.view(html! {
|
||||||
<div>
|
<div>
|
||||||
<h1> </h1>
|
<h1> "hello world!" </h1>
|
||||||
|
<h1> "hello world!" </h1>
|
||||||
|
<h1> "hello world!" </h1>
|
||||||
|
<h1> "hello world!" </h1>
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -23,15 +23,13 @@ impl<P: Properties> Component for FC<P> {
|
|||||||
|
|
||||||
/// The `Properties` trait defines any struct that can be constructed using a combination of default / optional fields.
|
/// The `Properties` trait defines any struct that can be constructed using a combination of default / optional fields.
|
||||||
/// Components take a "properties" object
|
/// Components take a "properties" object
|
||||||
pub trait Properties: 'static {
|
pub trait Properties {
|
||||||
fn new() -> Self;
|
fn call(&self, ptr: *const ()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto implement for no-prop components
|
// Auto implement for no-prop components
|
||||||
impl Properties for () {
|
impl Properties for () {
|
||||||
fn new() -> Self {
|
fn call(&self, ptr: *const ()) {}
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use std::{
|
|||||||
// todo: force lifetime of source into T as a valid lifetime too
|
// todo: force lifetime of source into T as a valid lifetime too
|
||||||
// it's definitely possible, just needs some more messing around
|
// it's definitely possible, just needs some more messing around
|
||||||
pub struct Context<'src> {
|
pub struct Context<'src> {
|
||||||
// pub struct Context<'src, PropType> {
|
pub(crate) scope: &'src Scope,
|
||||||
/// Direct access to the properties used to create this component.
|
/// Direct access to the properties used to create this component.
|
||||||
// pub props: &'src PropType,
|
// pub props: &'src PropType,
|
||||||
pub idx: AtomicUsize,
|
pub idx: AtomicUsize,
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
//! Useful, foundational hooks that 3rd parties can implement.
|
||||||
|
//! Currently implemented:
|
||||||
|
//! - use_ref
|
||||||
|
//! - use_state
|
||||||
|
|
||||||
|
pub use use_ref_def::use_ref;
|
||||||
|
pub use use_state_def::use_state;
|
||||||
|
|
||||||
|
mod use_state_def {
|
||||||
|
use crate::inner::*;
|
||||||
|
use std::{borrow::BorrowMut, cell::RefCell, ops::DerefMut, rc::Rc};
|
||||||
|
|
||||||
|
struct UseState<T: 'static> {
|
||||||
|
new_val: Rc<RefCell<Option<T>>>,
|
||||||
|
current_val: T,
|
||||||
|
caller: Box<dyn Fn(T) + 'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store state between component renders!
|
||||||
|
/// When called, this hook retrives a stored value and provides a setter to update that value.
|
||||||
|
/// When the setter is called, the component is re-ran with the new value.
|
||||||
|
///
|
||||||
|
/// This is behaves almost exactly the same way as React's "use_state".
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// ```ignore
|
||||||
|
/// static Example: FC<()> = |ctx| {
|
||||||
|
/// let (counter, set_counter) = use_state(ctx, || 0);
|
||||||
|
/// let increment = || set_couter(counter + 1);
|
||||||
|
/// let decrement = || set_couter(counter + 1);
|
||||||
|
///
|
||||||
|
/// html! {
|
||||||
|
/// <div>
|
||||||
|
/// <h1>"Counter: {counter}" </h1>
|
||||||
|
/// <button onclick={increment}> "Increment" </button>
|
||||||
|
/// <button onclick={decrement}> "Decrement" </button>
|
||||||
|
/// </div>
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn use_state<'a, T: 'static, F: FnOnce() -> T + 'static>(
|
||||||
|
ctx: &'_ Context<'a>,
|
||||||
|
initial_state_fn: F,
|
||||||
|
) -> (&'a T, &'a impl Fn(T)) {
|
||||||
|
ctx.use_hook(
|
||||||
|
move || UseState {
|
||||||
|
new_val: Rc::new(RefCell::new(None)),
|
||||||
|
current_val: initial_state_fn(),
|
||||||
|
caller: Box::new(|_| println!("setter called!")),
|
||||||
|
},
|
||||||
|
move |hook| {
|
||||||
|
let inner = hook.new_val.clone();
|
||||||
|
let scheduled_update = ctx.schedule_update();
|
||||||
|
|
||||||
|
// get ownership of the new val and replace the current with the new
|
||||||
|
// -> as_ref -> borrow_mut -> deref_mut -> take
|
||||||
|
// -> rc -> &RefCell -> RefMut -> &Option<T> -> T
|
||||||
|
if let Some(new_val) = hook.new_val.as_ref().borrow_mut().deref_mut().take() {
|
||||||
|
hook.current_val = new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: swap out the caller with a subscription call and an internal update
|
||||||
|
hook.caller = Box::new(move |new_val| {
|
||||||
|
// update the setter with the new value
|
||||||
|
let mut new_inner = inner.as_ref().borrow_mut();
|
||||||
|
*new_inner = Some(new_val);
|
||||||
|
|
||||||
|
// Ensure the component gets updated
|
||||||
|
scheduled_update();
|
||||||
|
});
|
||||||
|
|
||||||
|
// box gets derefed into a ref which is then taken as ref with the hook
|
||||||
|
(&hook.current_val, &hook.caller)
|
||||||
|
},
|
||||||
|
|_| {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod use_ref_def {
|
||||||
|
use crate::inner::*;
|
||||||
|
use std::{borrow::BorrowMut, cell::RefCell, ops::DerefMut, rc::Rc};
|
||||||
|
|
||||||
|
pub struct UseRef<T: 'static> {
|
||||||
|
_current: RefCell<T>,
|
||||||
|
}
|
||||||
|
impl<T: 'static> UseRef<T> {
|
||||||
|
fn new(val: T) -> Self {
|
||||||
|
Self {
|
||||||
|
_current: RefCell::new(val),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn modify(&self, modifier: impl FnOnce(&mut T)) {
|
||||||
|
let mut val = self._current.borrow_mut();
|
||||||
|
let val_as_ref = val.deref_mut();
|
||||||
|
modifier(val_as_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current(&self) -> std::cell::Ref<'_, T> {
|
||||||
|
self._current.borrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store a mutable value between renders!
|
||||||
|
/// To read the value, borrow the ref.
|
||||||
|
/// To change it, use modify.
|
||||||
|
/// 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: &'_ Context<'a>,
|
||||||
|
initial_state_fn: impl FnOnce() -> T + 'static,
|
||||||
|
) -> &'a UseRef<T> {
|
||||||
|
ctx.use_hook(|| UseRef::new(initial_state_fn()), |state| &*state, |_| {})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,6 +69,7 @@ pub mod component;
|
|||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod debug_renderer;
|
pub mod debug_renderer;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
pub mod hooks;
|
||||||
pub mod nodebuilder;
|
pub mod nodebuilder;
|
||||||
pub mod nodes;
|
pub mod nodes;
|
||||||
pub mod scope;
|
pub mod scope;
|
||||||
@@ -131,4 +132,6 @@ pub mod prelude {
|
|||||||
pub use crate::nodebuilder as builder;
|
pub use crate::nodebuilder as builder;
|
||||||
pub use dioxus_core_macro::fc;
|
pub use dioxus_core_macro::fc;
|
||||||
pub use dioxus_html_2::html;
|
pub use dioxus_html_2::html;
|
||||||
|
|
||||||
|
pub use crate::hooks::*;
|
||||||
}
|
}
|
||||||
+22
-12
@@ -37,7 +37,7 @@ mod vnode {
|
|||||||
Suspended,
|
Suspended,
|
||||||
|
|
||||||
/// A User-defined componen node (node type COMPONENT_NODE)
|
/// A User-defined componen node (node type COMPONENT_NODE)
|
||||||
Component(VComponent),
|
Component(VComponent<'src>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VNode<'a> {
|
impl<'a> VNode<'a> {
|
||||||
@@ -174,11 +174,7 @@ mod velement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An event listener.
|
/// An event listener.
|
||||||
pub struct Listener<'a>
|
pub struct Listener<'a> {
|
||||||
// pub struct Listener<'a, 'b>
|
|
||||||
// where
|
|
||||||
// 'b: 'a + 'static,
|
|
||||||
{
|
|
||||||
/// The type of event to listen for.
|
/// The type of event to listen for.
|
||||||
pub(crate) event: &'a str,
|
pub(crate) event: &'a str,
|
||||||
/// The callback to invoke when the event happens.
|
/// The callback to invoke when the event happens.
|
||||||
@@ -249,19 +245,33 @@ mod vtext {
|
|||||||
/// Only supports the functional syntax
|
/// Only supports the functional syntax
|
||||||
mod vcomponent {
|
mod vcomponent {
|
||||||
use crate::prelude::Properties;
|
use crate::prelude::Properties;
|
||||||
use std::{any::TypeId, fmt, future::Future};
|
use std::{any::TypeId, fmt, future::Future, marker::PhantomData};
|
||||||
|
|
||||||
use super::VNode;
|
use super::VNode;
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub struct VComponent {
|
pub struct VComponent<'src> {
|
||||||
// props_id: TypeId,
|
_p: PhantomData<&'src ()>,
|
||||||
|
runner: Box<dyn Properties + 'src>,
|
||||||
|
caller: *const (),
|
||||||
|
props_type: TypeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl<'src> PartialEq for CallerSource<'src> {
|
||||||
|
// fn eq(&self, other: &Self) -> bool {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// caller: Box<dyn Fn
|
||||||
|
// should we box the caller?
|
||||||
|
// probably, so we can call it again
|
||||||
|
//
|
||||||
|
// props_id: TypeId,
|
||||||
// callerIDs are unsafely coerced to function pointers
|
// callerIDs are unsafely coerced to function pointers
|
||||||
// This is okay because #1, we store the props_id and verify and 2# the html! macro rejects components not made this way
|
// This is okay because #1, we store the props_id and verify and 2# the html! macro rejects components not made this way
|
||||||
//
|
//
|
||||||
// Manually constructing the VComponent is not possible from 3rd party crates
|
// Manually constructing the VComponent is not possible from 3rd party crates
|
||||||
}
|
|
||||||
|
|
||||||
impl VComponent {
|
impl<'a> VComponent<'a> {
|
||||||
// /// Construct a VComponent directly from a function component
|
// /// Construct a VComponent directly from a function component
|
||||||
// /// This should be *very* fast - we store the function pointer and props type ID. It should also be small on the stack
|
// /// This should be *very* fast - we store the function pointer and props type ID. It should also be small on the stack
|
||||||
// pub fn from_fn<P: Properties>(f: FC<P>, props: P) -> Self {
|
// pub fn from_fn<P: Properties>(f: FC<P>, props: P) -> Self {
|
||||||
|
|||||||
@@ -47,18 +47,19 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_context<'runner, T: Properties>(
|
pub fn create_context<'a, T: Properties>(
|
||||||
&'runner mut self,
|
&'a mut self,
|
||||||
components: &'runner generational_arena::Arena<Scope>,
|
components: &'a generational_arena::Arena<Scope>,
|
||||||
props: &'runner T,
|
props: &'a T,
|
||||||
) -> Context {
|
) -> Context {
|
||||||
// ) -> Context<T> {
|
|
||||||
|
//
|
||||||
Context {
|
Context {
|
||||||
|
scope: &*self,
|
||||||
_p: PhantomData {},
|
_p: PhantomData {},
|
||||||
arena: &self.hook_arena,
|
arena: &self.hook_arena,
|
||||||
hooks: &self.hooks,
|
hooks: &self.hooks,
|
||||||
idx: 0.into(),
|
idx: 0.into(),
|
||||||
// props,
|
|
||||||
components,
|
components,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use dioxus_core::prelude::*;
|
pub use dioxus_core::prelude::*;
|
||||||
pub use dioxus_core_macro::fc;
|
pub use dioxus_core_macro::fc;
|
||||||
pub use dioxus_hooks::prelude::use_state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use dioxus_core::prelude::FC;
|
use dioxus_core::prelude::FC;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// mod hooks;
|
// mod hooks;
|
||||||
// pub use hooks::use_context;
|
// pub use hooks::use_context;
|
||||||
|
|
||||||
pub mod prelude {
|
// pub mod prelude {
|
||||||
use dioxus_core::prelude::Context;
|
// use dioxus_core::prelude::Context;
|
||||||
pub fn use_state<T, G>(ctx: &Context<G>, init: impl Fn() -> T) -> (T, impl Fn(T)) {
|
// pub fn use_state<T, G>(ctx: &Context<G>, init: impl Fn() -> T) -> (T, impl Fn(T)) {
|
||||||
let g = init();
|
// let g = init();
|
||||||
(g, |_| {})
|
// (g, |_| {})
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
use ::{
|
use ::{
|
||||||
proc_macro::TokenStream,
|
proc_macro::TokenStream,
|
||||||
proc_macro2::{Span, TokenStream as TokenStream2},
|
proc_macro2::{Span, TokenStream as TokenStream2},
|
||||||
proc_macro_hack::proc_macro_hack,
|
|
||||||
quote::{quote, ToTokens, TokenStreamExt},
|
quote::{quote, ToTokens, TokenStreamExt},
|
||||||
style_shared::Styles,
|
style_shared::Styles,
|
||||||
syn::{
|
syn::{
|
||||||
@@ -77,7 +76,6 @@ struct NodeList(Vec<MaybeExpr<Node>>);
|
|||||||
|
|
||||||
impl ToTokens for ToToksCtx<&NodeList> {
|
impl ToTokens for ToToksCtx<&NodeList> {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||||
// let ctx = &self.ctx;
|
|
||||||
let nodes = self.inner.0.iter().map(|node| self.recurse(node));
|
let nodes = self.inner.0.iter().map(|node| self.recurse(node));
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
dioxus::bumpalo::vec![in bump;
|
dioxus::bumpalo::vec![in bump;
|
||||||
@@ -226,12 +224,17 @@ impl Parse for Attr {
|
|||||||
let mut name = Ident::parse_any(s)?;
|
let mut name = Ident::parse_any(s)?;
|
||||||
let name_str = name.to_string();
|
let name_str = name.to_string();
|
||||||
s.parse::<Token![=]>()?;
|
s.parse::<Token![=]>()?;
|
||||||
|
|
||||||
|
// Check if this is an event handler
|
||||||
|
// If so, parse into literal tokens
|
||||||
let ty = if name_str.starts_with("on") {
|
let ty = if name_str.starts_with("on") {
|
||||||
// remove the "on" bit
|
// remove the "on" bit
|
||||||
name = Ident::new(&name_str.trim_start_matches("on"), name.span());
|
name = Ident::new(&name_str.trim_start_matches("on"), name.span());
|
||||||
let content;
|
let content;
|
||||||
syn::braced!(content in s);
|
syn::braced!(content in s);
|
||||||
|
// AttrType::Value(content.parse()?)
|
||||||
AttrType::Event(content.parse()?)
|
AttrType::Event(content.parse()?)
|
||||||
|
// AttrType::Event(content.parse()?)
|
||||||
} else {
|
} else {
|
||||||
let lit_str = if name_str == "style" && s.peek(token::Brace) {
|
let lit_str = if name_str == "style" && s.peek(token::Brace) {
|
||||||
// special-case to deal with literal styles.
|
// special-case to deal with literal styles.
|
||||||
@@ -332,23 +335,16 @@ where
|
|||||||
|
|
||||||
/// ToTokens context
|
/// ToTokens context
|
||||||
struct ToToksCtx<T> {
|
struct ToToksCtx<T> {
|
||||||
// struct ToToksCtx<'a, T> {
|
|
||||||
inner: T,
|
inner: T,
|
||||||
// ctx: &'a Ident,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> ToToksCtx<T> {
|
impl<'a, T> ToToksCtx<T> {
|
||||||
fn new(inner: T) -> Self {
|
fn new(inner: T) -> Self {
|
||||||
// fn new(ctx: &'a Ident, inner: T) -> Self {
|
|
||||||
ToToksCtx { inner }
|
ToToksCtx { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recurse<U>(&self, inner: U) -> ToToksCtx<U> {
|
fn recurse<U>(&self, inner: U) -> ToToksCtx<U> {
|
||||||
// fn recurse<U>(&self, inner: U) -> ToToksCtx<'a, U> {
|
ToToksCtx { inner }
|
||||||
ToToksCtx {
|
|
||||||
// ctx: &self.ctx,
|
|
||||||
inner,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user