dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

[Docs]: Update Docs for Proper `#[layout]` and `#[end_layout]` Macros Usage in Enums

Open wiseaidev opened this issue 1 year ago • 3 comments

Hiya ( ´ ω ` )ノ゙,

This is not a critical issue, but I’ve noticed a bug with layout and routes ordering when defining multiple layouts for different pages.

Here’s an example that works:

#[derive(Clone, Routable, Debug, PartialEq, Serialize, Deserialize)]  
pub enum Route {  
    #[layout(HomeNavBar)]  
    #[route("/")]  
    Home {},  
    #[end_layout]  

    #[layout(LoginNavBar)]  
    #[route("/login")]  
    Login {},  
    #[end_layout]  

    #[route("/dashboard")]  
    Dashboard {},  
}  

However, if you reorder the routes like this:

#[derive(Clone, Routable, Debug, PartialEq, Serialize, Deserialize)]  
pub enum Route {  
    #[layout(HomeNavBar)]  
    #[route("/")]  
    Home {},  
    #[end_layout]

    #[route("/dashboard")] // Notice this route between the layouts  
    Dashboard {},  

    #[layout(LoginNavBar)]  
    #[route("/login")]  
    Login {},  
    #[end_layout]  
}  

The routing doesn’t work as expected.

Just wanted to raise this to your attention.

Best

wiseaidev avatar Nov 13 '24 12:11 wiseaidev

I was not able to reproduce this issue with the git version of dioxus with either version of the router. Here is my attempt: https://github.com/ealmloff/fail-repo-3211

ealmloff avatar Nov 13 '24 14:11 ealmloff

I was not able to reproduce this issue with the git version of dioxus with either version of the router. Here is my attempt: https://github.com/ealmloff/fail-repo-3211

Thanks for the reply! But, your enum router example doesn't include a #[end_layout] macro at the end to close the corresponding #[layout] macro. In this case, it will raise:

error: expected identifier, found `}`
  --> src/main.rs:19:1
   |
4  | pub enum Route {  
   |          ----- while parsing this enum
...
19 | }  
   | ^ expected identifier
   |
   = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`

  ❌ Build failed.
| 💼 Waiting to start building the project...                                   Error: 🚫 Serving project failed:

However, I realized that in Rust, macros are designed to modify the item or block immediately following them. Since #[end_layout] isn't attached to any item, it causes a bug. I think it is better to update the documentation to inform users that layouts must be properly scoped and ensure each #[layout] is correctly closed or inferred by the macro.

wiseaidev avatar Nov 13 '24 17:11 wiseaidev

bump, its not really the end of the world but its a very hard to figure out bug if you unknowingly put anything above a layout like they said just something quick that mentions this would be great

not-a-cowfr avatar Apr 01 '25 18:04 not-a-cowfr

Would it be possible to somehow still allow closing macros without following routes? If it's not possible because of macro syntax limitations, what about adding some placeholder enum variant at the end?

I tried adding such variant myself, without any #[route] macros, but this doesn't work, as "Routable variants must either have a #[route(..)] attribute or a #[child(..)] attribute". Adding a placeholder macro also won't work, as then the component won't be found.

So, maybe the router could allow a specifically-named enum variant at the end, without any #[route] macros associated?

filips123 avatar Aug 14 '25 16:08 filips123