Feat: WIP
This commit is contained in:
1 parent
cd20d3c168
commit
ce34d0dfcd
13 files changed
+275
-18
No files matched your search
@@ -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"
|
||||
@@ -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>
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -9,4 +9,4 @@ repository = "https://github.com/chinedufn/percy"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.0"
|
||||
lazy_static = "1.4.0"
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in new issue
Block a user