docs: more work on docs

This commit is contained in:
Jonathan Kelley committed 2021-06-25 09:31:13 -04:00
1 parent 4ecfc241e2
commit daa9bd82c3
5 files changed
+53 -64

No files matched your search

+1
View File
@@ -58,3 +58,4 @@ textarea
noderefs noderefs
wasm wasm
7ns 7ns
attr
+5 -3
View File
@@ -111,11 +111,13 @@ Dioxus is heavily inspired by React, but we want your transition to feel like an
| Null components | ✅ | ✅ | allow returning no components | | Null components | ✅ | ✅ | allow returning no components |
| No-div components | ✅ | ✅ | components that render components | | No-div components | ✅ | ✅ | components that render components |
| Fragments | ✅ | ✅ | rsx! can return multiple elements without a root | | Fragments | ✅ | ✅ | rsx! can return multiple elements without a root |
| Manual Props | 👀 | ✅ | Manually pass in props | | Manual Props | ✅ | ✅ | Manually pass in props with spread syntax |
| NodeRef | 👀 | ✅ | gain direct access to nodes |
| Controlled Inputs | ✅ | ✅ | stateful wrappers around inputs | | Controlled Inputs | ✅ | ✅ | stateful wrappers around inputs |
| CSS/Inline Styles | 🛠 | ✅ | syntax for inline/conditional styles |
| 1st class global state | 🛠 | ✅ | redux/recoil/mobx on top of context | | 1st class global state | 🛠 | ✅ | redux/recoil/mobx on top of context |
| NodeRef | 🛠 | ✅ | gain direct access to nodes [1] |
| CSS/Inline Styles | 🛠 | ✅ | syntax for inline styles/attribute groups |
[1] Currently blocked until we figure out a cross-platform way of exposing an imperative Node API
### Phase 2: Advanced Toolkits ### Phase 2: Advanced Toolkits
+2 -3
View File
@@ -162,11 +162,10 @@ static Example: FC<()> = |cx| {
// Can take optional properties // Can take optional properties
Taller { a: "asd" } Taller { a: "asd" }
// Can pass in props directly // Can pass in props directly as an expression
{{ {{
todo!("this neesd to be implemented");
let props = TallerProps {a: "hello"}; let props = TallerProps {a: "hello"};
rsx!(Taller {a: "a"}) rsx!(Taller { ..props })
}} }}
// Can take children // Can take children
+19 -40
View File
@@ -1,52 +1,31 @@
# Parity with React # Parity with React
Sorted by priority Parity has moved to the homepage
| Feature | Dioxus | React | Notes |
| ---------------------- | ------ | ----- | ------------------------------------------------ |
| ----- Phase 1 ----- | ----- | ----- | ----- |
| Conditional Rendering | ✅ | ✅ | if/then to hide/show component |
| Map, Iterator | ✅ | ✅ | map/filter/reduce rsx! |
| Keyed Components | ✅ | ✅ | advanced diffing with keys |
| Web | ✅ | ✅ | renderer for web browser |
| Desktop (webview) | ✅ | ✅ | renderer for desktop |
| Context | ✅ | ✅ | share state through the tree |
| Hook | ✅ | ✅ | memory cells in components |
| SSR | ✅ | ✅ | render directly to string |
| Runs natively | ✅ | 👀 | runs as a portable binary w/o a runtime (Node) |
| Component Children | ✅ | ✅ | cx.children() as a list of nodes |
| Null components | ✅ | ✅ | allow returning no components |
| No-div components | ✅ | ✅ | components that render components |
| Fragments | ✅ | ✅ | rsx! can return multiple elements without a root |
| Manual Props | 👀 | ✅ | Manually pass in props |
| NodeRef | 👀 | ✅ | gain direct access to nodes |
| Controlled Inputs | ✅ | ✅ | stateful wrappers around inputs |
| CSS/Inline Styles | 🛠 | ✅ | syntax for inline/conditional styles |
| 1st class global state | 🛠 | ✅ | redux/recoil/mobx on top of context |
| ----- Phase 2 ----- | ----- | ----- | ----- |
| 1st class router | 👀 | ✅ | Hook built on top of history |
| Assets | 👀 | ✅ | include css/svg/img url statically |
| Integrated classnames | 🛠 | 👀 | built-in `classnames` |
| Suspense | 👀 | 👀 | schedule future render from future/promise |
| Transition | 👀 | 👀 | High-level control over suspense |
| Animation | 👀 | ✅ | Spring-style animations |
| Mobile | 👀 | ✅ | Render with cacao |
| Desktop (native) | 👀 | ✅ | Render with native desktop |
| 3D Renderer | 👀 | ✅ | react-three-fiber |
| ----- Phase 3 ----- | ----- | ----- | ----- |
| Portal | 👀 | ✅ | cast elements through tree |
| Error/Panic boundary | 👀 | ✅ | catch panics and display custom BSOD |
| Code-splitting | 👀 | ✅ | Make bundle smaller/lazy |
| LiveView | 👀 | 👀 | Example for SSR + WASM apps |
## Required services: ## Required services:
--- ---
Gloo is covering a lot of these. We want to build hooks around these, and provide examples on how to use them. Gloo is covering a lot of these. We want to build hooks around these and provide examples on how to use them.
https://github.com/rustwasm/gloo https://github.com/rustwasm/gloo
If the gloo service doesn't exist, then we need to contribute to the project For example, resize observer would function like this:
```rust
static Example: FC<()> = |cx| {
let observer = use_resize_observer();
cx.render(rsx!(
div { ref: observer.node_ref
"Size, x: {observer.x} y: {observer.y}"
}
))
}
```
However, resize observing is _not_ cross-platform, so this hook (internally) needs to abstract over the rendering platform.
For other services, we shell out to gloo. If the gloo service doesn't exist, then we need to contribute to the project to make sure it exists.
| Service | Hook examples | Current Projects | | Service | Hook examples | Current Projects |
| ---------------------------- | ------------- | ---------------- | | ---------------------------- | ------------- | ---------------- |
+26 -18
View File
@@ -27,21 +27,23 @@ pub struct Component {
name: syn::Path, name: syn::Path,
body: Vec<ComponentField>, body: Vec<ComponentField>,
children: Vec<Node>, children: Vec<Node>,
manual_props: Option<Expr>,
} }
impl Parse for Component { impl Parse for Component {
fn parse(s: ParseStream) -> Result<Self> { fn parse(stream: ParseStream) -> Result<Self> {
// let name = s.parse::<syn::ExprPath>()?; // let name = s.parse::<syn::ExprPath>()?;
// todo: look into somehow getting the crate/super/etc // todo: look into somehow getting the crate/super/etc
let name = syn::Path::parse_mod_style(s)?; let name = syn::Path::parse_mod_style(stream)?;
// parse the guts // parse the guts
let content: ParseBuffer; let content: ParseBuffer;
syn::braced!(content in s); syn::braced!(content in stream);
let mut body: Vec<ComponentField> = Vec::new(); let mut body: Vec<ComponentField> = Vec::new();
let mut children: Vec<Node> = Vec::new(); let mut children: Vec<Node> = Vec::new();
let mut manual_props = None;
'parsing: loop { 'parsing: loop {
// [1] Break if empty // [1] Break if empty
@@ -49,15 +51,10 @@ impl Parse for Component {
break 'parsing; break 'parsing;
} }
if content.peek(token::Brace) && content.peek2(Token![...]) { if content.peek(Token![..]) {
let inner: ParseBuffer; content.parse::<Token![..]>()?;
syn::braced!(inner in content); manual_props = Some(content.parse::<Expr>()?);
if inner.peek(Token![...]) { } else if content.peek(Ident) && content.peek2(Token![:]) {
todo!("Inline props not yet supported");
}
}
if content.peek(Ident) && content.peek2(Token![:]) {
body.push(content.parse::<ComponentField>()?); body.push(content.parse::<ComponentField>()?);
} else { } else {
children.push(content.parse::<Node>()?); children.push(content.parse::<Node>()?);
@@ -74,6 +71,7 @@ impl Parse for Component {
name, name,
body, body,
children, children,
manual_props,
}) })
} }
} }
@@ -82,8 +80,13 @@ impl ToTokens for Component {
fn to_tokens(&self, tokens: &mut TokenStream2) { fn to_tokens(&self, tokens: &mut TokenStream2) {
let name = &self.name; let name = &self.name;
let mut builder = quote! { let using_manual_override = self.manual_props.is_some();
fc_to_builder(#name)
let mut builder = {
match &self.manual_props {
Some(manual_props) => quote! { #manual_props },
None => quote! { fc_to_builder(#name) },
}
}; };
let mut has_key = None; let mut has_key = None;
@@ -92,13 +95,18 @@ impl ToTokens for Component {
if field.name.to_string() == "key" { if field.name.to_string() == "key" {
has_key = Some(field); has_key = Some(field);
} else { } else {
builder.append_all(quote! {#field}); match using_manual_override {
true => panic!("Currently we don't support manual props and prop fields. Choose either manual props or prop fields"),
false => builder.append_all(quote! {#field}),
}
} }
} }
builder.append_all(quote! { if !using_manual_override {
.build() builder.append_all(quote! {
}); .build()
});
}
let key_token = match has_key { let key_token = match has_key {
Some(field) => { Some(field) => {