mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 06:34:20 +00:00
docs: more work on docs
This commit is contained in:
parent
4ecfc241e2
commit
daa9bd82c3
5 changed files with 53 additions and 64 deletions
1
.vscode/spellright.dict
vendored
1
.vscode/spellright.dict
vendored
|
@ -58,3 +58,4 @@ textarea
|
|||
noderefs
|
||||
wasm
|
||||
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 |
|
||||
| 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 |
|
||||
| Manual Props | ✅ | ✅ | Manually pass in props with spread syntax |
|
||||
| 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 |
|
||||
| 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
|
||||
|
||||
|
|
|
@ -162,11 +162,10 @@ static Example: FC<()> = |cx| {
|
|||
// Can take optional properties
|
||||
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"};
|
||||
rsx!(Taller {a: "a"})
|
||||
rsx!(Taller { ..props })
|
||||
}}
|
||||
|
||||
// Can take children
|
||||
|
|
|
@ -1,52 +1,31 @@
|
|||
# Parity with React
|
||||
|
||||
Sorted by priority
|
||||
|
||||
| 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 |
|
||||
Parity has moved to the homepage
|
||||
|
||||
## 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
|
||||
|
||||
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 |
|
||||
| ---------------------------- | ------------- | ---------------- |
|
||||
|
|
|
@ -27,21 +27,23 @@ pub struct Component {
|
|||
name: syn::Path,
|
||||
body: Vec<ComponentField>,
|
||||
children: Vec<Node>,
|
||||
manual_props: Option<Expr>,
|
||||
}
|
||||
|
||||
impl Parse for Component {
|
||||
fn parse(s: ParseStream) -> Result<Self> {
|
||||
fn parse(stream: ParseStream) -> Result<Self> {
|
||||
// let name = s.parse::<syn::ExprPath>()?;
|
||||
// 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
|
||||
let content: ParseBuffer;
|
||||
syn::braced!(content in s);
|
||||
syn::braced!(content in stream);
|
||||
|
||||
let mut body: Vec<ComponentField> = Vec::new();
|
||||
let mut children: Vec<Node> = Vec::new();
|
||||
let mut manual_props = None;
|
||||
|
||||
'parsing: loop {
|
||||
// [1] Break if empty
|
||||
|
@ -49,15 +51,10 @@ impl Parse for Component {
|
|||
break 'parsing;
|
||||
}
|
||||
|
||||
if content.peek(token::Brace) && content.peek2(Token![...]) {
|
||||
let inner: ParseBuffer;
|
||||
syn::braced!(inner in content);
|
||||
if inner.peek(Token![...]) {
|
||||
todo!("Inline props not yet supported");
|
||||
}
|
||||
}
|
||||
|
||||
if content.peek(Ident) && content.peek2(Token![:]) {
|
||||
if content.peek(Token![..]) {
|
||||
content.parse::<Token![..]>()?;
|
||||
manual_props = Some(content.parse::<Expr>()?);
|
||||
} else if content.peek(Ident) && content.peek2(Token![:]) {
|
||||
body.push(content.parse::<ComponentField>()?);
|
||||
} else {
|
||||
children.push(content.parse::<Node>()?);
|
||||
|
@ -74,6 +71,7 @@ impl Parse for Component {
|
|||
name,
|
||||
body,
|
||||
children,
|
||||
manual_props,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -82,8 +80,13 @@ impl ToTokens for Component {
|
|||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||
let name = &self.name;
|
||||
|
||||
let mut builder = quote! {
|
||||
fc_to_builder(#name)
|
||||
let using_manual_override = self.manual_props.is_some();
|
||||
|
||||
let mut builder = {
|
||||
match &self.manual_props {
|
||||
Some(manual_props) => quote! { #manual_props },
|
||||
None => quote! { fc_to_builder(#name) },
|
||||
}
|
||||
};
|
||||
|
||||
let mut has_key = None;
|
||||
|
@ -92,13 +95,18 @@ impl ToTokens for Component {
|
|||
if field.name.to_string() == "key" {
|
||||
has_key = Some(field);
|
||||
} 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! {
|
||||
.build()
|
||||
});
|
||||
if !using_manual_override {
|
||||
builder.append_all(quote! {
|
||||
.build()
|
||||
});
|
||||
}
|
||||
|
||||
let key_token = match has_key {
|
||||
Some(field) => {
|
||||
|
|
Loading…
Reference in a new issue