Parcourir la source

docs: more work on docs

Jonathan Kelley il y a 4 ans
Parent
commit
daa9bd8
5 fichiers modifiés avec 53 ajouts et 64 suppressions
  1. 1 0
      .vscode/spellright.dict
  2. 5 3
      README.md
  3. 2 3
      examples/rsx_usage.rs
  4. 19 40
      notes/Parity.md
  5. 26 18
      packages/core-macro/src/rsx/component.rs

+ 1 - 0
.vscode/spellright.dict

@@ -58,3 +58,4 @@ textarea
 noderefs
 wasm
 7ns
+attr

+ 5 - 3
README.md

@@ -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
 

+ 2 - 3
examples/rsx_usage.rs

@@ -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

+ 19 - 40
notes/Parity.md

@@ -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 |
 | ---------------------------- | ------------- | ---------------- |

+ 26 - 18
packages/core-macro/src/rsx/component.rs

@@ -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) => {