Hiya!
I've been using Leptos for a while now (ever since building this crate), and I've noticed that working with the view! macro can be quite cumbersome when adding conditional logic (if-else) inside the macro. Let me explain with some examples:
The Problem
To add if-else logic in view!, it always has to be wrapped in a closure ({move ||}). Here's a complex example:
<div class="wallet-info">
{move ||
if connected.get() {
Some(view!{
{move ||
if let Some(key) = phantom_wallet_adapter.get().public_key() {
view!{
<p>"Connected Wallet: " {move || phantom_wallet_adapter.get().name()} </p>
<p>"Connected Public Key: " {move || key.to_string() } </p>
<div class="forms">
<div class="send-sol-form">
<h2 class="form-title">{ "Transfer SOL" }</h2>
<form on:submit={transfer_sol_phantom}>
<div class="form-group">
<label for="destination-address">
{ "Destination Address" }
</label>
<input
id="destination-address"
type="text"
class="form-control"
node_ref={input_dest_ref}
required=true
value=dest
/>
</div>
<div class="form-group">
<label for="sol-amount">
{ "SOL Amount (in lamports)" }
</label>
<input
id="sol-amount"
type="number"
class="form-control"
node_ref={input_amount_ref}
required=true
value=amount
/>
</div>
<button type="submit" class="submit-button">{ "Send" }</button>
</form>
</div>
<div class="sign-form">
<h2 class="form-title">{ "Sign Message" }</h2>
<form on:submit={sign_msg_phantom}>
<div class="form-group">
<label for="message">
{ "Message" }
</label>
<input
id="Message"
type="text"
class="form-control"
node_ref={input_msg_ref}
required=true
value=msg
/>
</div>
<button type="submit" class="submit-button">{ "Sign" }</button>
</form>
</div>
</div>
{move ||
if confirmed.get() {
Some(view!{
<div class="transaction-info">
<p>{ "Transaction Successful!" }</p>
<a
href={format!("https://solscan.io/tx/{}", sig.get())}
target="_blank"
rel="noopener noreferrer"
class="view-transaction-button"
>
{ "View Transaction" }
</a>
</div>
})
} else {
None
}
}
}
} else if let Some(key) = solflare_wallet_adapter.get().public_key() {
view!{
<p>"Connected Wallet: " {move || solflare_wallet_adapter.get().name()} </p>
<p>"Connected Public Key: " {move || key.to_string() } </p>
}
} else {
view!{
<p>"Connected but no wallet info available"</p>
<p>{}</p>
}
}
}
})
} else {
None
}
}
</div>
This setup becomes messy and hard to read or maintain when handling complex structures.
- Closure Wrapping: Every conditional requires
{move || }.
- Tag Type Consistency: Both branches of the
if-else must use the same HTML tag type, making it impossible to render different tags (e.g., <input> in one branch and <textarea> in the other).
- Attribute Type Consistency: Even attributes within the same tag must have the same type in both branches. For example:
if something {
view! {
<input class="str type" />
}
} else {
view! {
<input class={"string type".to_string()} />
}
}
The above fails because the class attribute types differ (&str vs. String).
Real-World Frustration
When I was building a crate to simplify input components for WASM frameworks, I found these limitations made it frustrating to handle dynamic, conditional logic while keeping the code clean and maintainable.
Suggestion
To improve usability and maintainability of the view! macro:
- Remove Tag-Type Restrictions: Allow different HTML tag types in each branch of the
if-else if optional, when wrapped with Some().
if something {
view! {
Some(<input />)
}
} else {
view! {
Some(<textarea />
}
}
- Relax Attribute Type Matching: Automatically coerce attribute types to avoid unnecessary type mismatches.
- Simplify Closures: Minimize or remove the need for
{move ||} closures to simplify writing dynamic logic.
This would make it far easier to write concise and readable logic inside view!, especially for more complex use cases.
Thanks for considering this! 😊
Best!
Hiya!
I've been using Leptos for a while now (ever since building this crate), and I've noticed that working with the
view!macro can be quite cumbersome when adding conditional logic (if-else) inside the macro. Let me explain with some examples:The Problem
To add
if-elselogic inview!, it always has to be wrapped in a closure ({move ||}). Here's a complex example:This setup becomes messy and hard to read or maintain when handling complex structures.
{move || }.if-elsemust use the same HTML tag type, making it impossible to render different tags (e.g.,<input>in one branch and<textarea>in the other).The above fails because the
classattribute types differ (&strvs.String).Real-World Frustration
When I was building a crate to simplify input components for WASM frameworks, I found these limitations made it frustrating to handle dynamic, conditional logic while keeping the code clean and maintainable.
Suggestion
To improve usability and maintainability of the
view!macro:if-elseif optional, when wrapped withSome().{move ||}closures to simplify writing dynamic logic.This would make it far easier to write concise and readable logic inside
view!, especially for more complex use cases.Thanks for considering this! 😊
Best!