Feat: WIP

This commit is contained in:
Jonathan Kelley committed 2021-01-14 20:56:28 -05:00
1 parent cd20d3c168
commit ce34d0dfcd
13 files changed
+275 -18

No files matched your search

+5
View File
@@ -9,3 +9,8 @@ edition = "2018"
[dependencies]
generational-arena = "0.2.8"
typed-arena = "2.0.1"
virtual-dom-rs = { path = "../virtual-dom-rs" }
virtual-node = { path = "../virtual-node" }
html-macro = { path = "../html-macro" }
# web-sys = "0.3.46"
# js-sys = "0.3.46"
+75
View File
@@ -0,0 +1,75 @@
use std::future::Future;
use dioxus_core::{component::AnyContext, prelude::*};
use virtual_dom_rs::Closure;
pub fn main() {
let dom = VirtualDom::new(root);
let mut renderer = TextRenderer::new(dom);
let output = renderer.render();
}
fn root(ctx: &mut AnyContext) -> VirtualNode {
// the regular html syntax
// html! {
// <html>
// <Head />
// <Body />
// <Footer />
// </html>
// }
// or a manually crated vnode
{
let mut node_0 = VirtualNode::element("div");
let mut node_1: IterableNodes = ("Hello world!").into();
node_1.first().insert_space_before_text();
let mut node_2 = VirtualNode::element("button");
{
// let closure = Closure::wrap(Box::new(|_| {}) as Box<FnMut(_)>);
// let closure_rc = std::rc::Rc::new(closure);
// node_2
// .as_velement_mut()
// .expect("Not an element")
// .events
// .0
// .insert("onclick".to_string(), closure_rc);
}
if let Some(ref mut element_node) = node_0.as_velement_mut() {
element_node.children.extend(node_1.into_iter());
}
if let Some(ref mut element_node) = node_0.as_velement_mut() {
element_node.children.extend(node_2.into_iter());
}
VirtualNode
node_0
}
}
fn Head(ctx: &mut AnyContext) -> VirtualNode {
html! {
<head>
{"Head Section"}
</head>
}
}
fn Body(ctx: &mut AnyContext) -> VirtualNode {
html! {
<body>
{"Footer Section"}
</body>
}
}
fn Footer(ctx: &mut AnyContext) -> VirtualNode {
html! {
<div>
{"Footer Section"}
</div>
}
}
+91
View File
@@ -1 +1,92 @@
use html_macro::html;
use virtual_node::{IterableNodes, VElement, VirtualNode};
/// A re-export of everything to get macros working smoothly
pub mod prelude {
pub use crate::component::Context;
pub use crate::renderer::TextRenderer;
pub use crate::types::FC;
pub use crate::virtual_dom::VirtualDom;
pub use html_macro::html;
pub use virtual_node::{IterableNodes, VirtualNode};
}
pub mod virtual_dom {
use super::*;
pub struct VirtualDom {}
impl VirtualDom {
pub fn new(root: types::FC) -> Self {
Self {}
}
}
}
/// Virtual Node Support
pub mod nodes {
pub type VNode = virtual_node::VirtualNode;
// pub enum VNode {
// VText,
// VElement,
// VComponent,
// }
}
/// Example on how to craft a renderer that interacts with the VirtualDom
pub mod renderer {
use crate::virtual_dom::VirtualDom;
use super::*;
/// Renders a full Dioxus app to a String
///
pub struct TextRenderer {}
impl TextRenderer {
/// Create a new Text Renderer which renders the VirtualDom to a string
pub fn new(dom: VirtualDom) -> Self {
Self {}
}
pub fn render(&mut self) -> String {
todo!()
}
}
}
pub mod component {
/// A wrapper around component contexts that hides component property types
pub struct AnyContext {}
pub struct Context<T> {
_props: std::marker::PhantomData<T>,
}
pub trait Properties {}
impl Properties for () {}
fn test() {}
}
/// Utility types that wrap internals
pub mod types {
use super::*;
use component::{AnyContext, Context};
use nodes::VNode;
pub type FC = fn(&mut AnyContext) -> VNode;
}
// #[cg(test)]
mod integration_tests {
use crate::prelude::*;
/// Test a basic usage of a virtual dom + text renderer combo
#[test]
fn simple_integration() {
let dom = VirtualDom::new(|_| html! { <div>Hello World!</div> });
let mut renderer = TextRenderer::new(dom);
let output = renderer.render();
}
}
@@ -111,6 +111,7 @@ custom components: https://chinedufn.github.io/percy/html-macro/custom-component
})
.collect();
// TODO @Jon - this is where we need to start injecting new logic about props/children etc
let node = quote! {
let mut #var_name_component = #component_ident { #(#component_props),* };
let mut #var_name_node = #var_name_component.render();
+1 -1
View File
@@ -9,4 +9,4 @@ repository = "https://github.com/chinedufn/percy"
edition = "2018"
[dependencies]
lazy_static = "1.0"
lazy_static = "1.4.0"
+14
View File
@@ -57,16 +57,22 @@ pub enum VirtualNode {
/// order to enable custom methods like `create_text_node()` on the
/// wrapped type.
Text(VText),
/// A User-defined componen node (node type COMPONENT_NODE)
Component(VComponent),
}
#[derive(PartialEq)]
pub struct VElement {
/// The HTML tag, such as "div"
pub tag: String,
/// HTML attributes such as id, class, style, etc
pub attrs: HashMap<String, String>,
/// Events that will get added to your real DOM element via `.addEventListener`
pub events: Events,
/// The children of this `VirtualNode`. So a <div> <em></em> </div> structure would
/// have a parent div and one child, em.
pub children: Vec<VirtualNode>,
@@ -77,6 +83,9 @@ pub struct VText {
pub text: String,
}
#[derive(PartialEq)]
pub struct VComponent {}
impl VirtualNode {
/// Create a new virtual element node with a given tag.
///
@@ -162,6 +171,7 @@ impl VirtualNode {
CreatedNode::without_closures(text_node.create_text_node())
}
VirtualNode::Element(element_node) => element_node.create_element_node().into(),
VirtualNode::Component(_) => todo!("WIP on Component Syntax"),
}
}
@@ -302,6 +312,9 @@ impl VElement {
element.append_child(&child_elem).unwrap();
}
VirtualNode::Component(_) => {
todo!("WIP on Component Syntax")
}
}
});
@@ -529,6 +542,7 @@ impl fmt::Debug for VirtualNode {
match self {
VirtualNode::Element(e) => write!(f, "Node::{:?}", e),
VirtualNode::Text(t) => write!(f, "Node::{:?}", t),
VirtualNode::Component(c) => write!(f, "Node::{:?}", c),
}
}
}
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "dioxus-web"
version = "0.0.0"
authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+1
View File
@@ -0,0 +1 @@