docs: more work on docs
This commit is contained in:
1 parent
4ecfc241e2
commit
daa9bd82c3
5 files changed
+53
-64
No files matched your search
Vendored
+1
@@ -58,3 +58,4 @@ textarea
|
|||||||
noderefs
|
noderefs
|
||||||
wasm
|
wasm
|
||||||
7ns
|
7ns
|
||||||
|
attr
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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 |
|
||||||
| ---------------------------- | ------------- | ---------------- |
|
| ---------------------------- | ------------- | ---------------- |
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
Reference in new issue
Block a user