Skip to content

Commit

Permalink
made blocks parse as blocks, updated docs, excluded npm artifacts in …
Browse files Browse the repository at this point in the history
…gitignore
  • Loading branch information
its-the-shrimp committed Oct 13, 2023
1 parent 04909dd commit 0c43713
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ target/
*.iml
/.idea/
/.vscode/

# artifacts from tools like prettier
node_modules/
package.json
package-lock.json
28 changes: 22 additions & 6 deletions packages/yew-macro/src/html_tree/html_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use quote::{quote, quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream, Result};
use syn::spanned::Spanned;
use syn::{Expr, Lit};
use syn::{Lit, Block, Stmt};

use super::ToNodeIterator;
use crate::stringify::Stringify;
use crate::PeekValue;

pub enum HtmlNode {
Literal(Box<Lit>),
Expression(Box<Expr>),
Expression(Vec<Stmt>),
}

impl Parse for HtmlNode {
Expand All @@ -23,7 +23,7 @@ impl Parse for HtmlNode {
}
HtmlNode::Literal(Box::new(lit))
} else {
HtmlNode::Expression(Box::new(input.parse()?))
HtmlNode::Expression(Block::parse_within(input)?)
};

Ok(node)
Expand All @@ -49,7 +49,15 @@ impl ToTokens for HtmlNode {
let sr = lit.stringify();
quote_spanned! {lit.span()=> ::yew::virtual_dom::VText::new(#sr) }
}
HtmlNode::Expression(expr) => quote! {#expr},
HtmlNode::Expression(stmts) => if let [expr] = &stmts[..] {
quote! {#expr}
} else {
let mut block = TokenStream::new();
for stmt in stmts.iter() {
stmt.to_tokens(&mut block)
}
quote_spanned! {block.span()=> {#block}}
}
});
}
}
Expand All @@ -58,11 +66,19 @@ impl ToNodeIterator for HtmlNode {
fn to_node_iterator_stream(&self) -> Option<TokenStream> {
match self {
HtmlNode::Literal(_) => None,
HtmlNode::Expression(expr) => {
// NodeSeq turns both Into<T> and Vec<Into<T>> into IntoIterator<Item = T>
HtmlNode::Expression(stmts) => if let [expr] = &stmts[..] {
Some(quote_spanned! {expr.span().resolved_at(Span::call_site())=>
::std::convert::Into::<::yew::utils::NodeSeq<_, _>>::into(#expr)
})
} else {
let mut block = TokenStream::new();
for stmt in stmts.iter() {
stmt.to_tokens(&mut block)
}
// NodeSeq turns both Into<T> and Vec<Into<T>> into IntoIterator<Item = T>
Some(quote_spanned! {block.span().resolved_at(Span::call_site())=>
::std::convert::Into::<::yew::utils::NodeSeq<_, _>>::into({#block})
})
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions packages/yew-macro/tests/html_macro/block-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,11 @@ fn main() {
{ for ::std::iter::Iterator::map(0..3, item) }
</ul>
};

::yew::html! {
<span>{
let version = 0.21;
::std::format!("Yew {version}")
}</span>
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn HelloWorld(props: &Props) -> Html {
:::note
If you have an internal pure component that makes no use of hooks and other component machinery, you can often write it instead
as a normal function returning `Html` and avoid a bit of overhead for Yew, related to running the component lifecycle. Use
[expression syntax](concepts/html/literals-and-expressions.mdx#expressions) to render them in `html!`.
[code block syntax](concepts/html/literals-and-code-blocks.mdx#code-blocks) to render them in `html!`.
:::

## Impure components
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: 'Literals and Expressions'
title: 'Literals and Code Blocks'
---

## Literals
Expand Down Expand Up @@ -27,16 +27,19 @@ html!{

## Expressions

You can insert expressions in your HTML using `{}` blocks, as long as they resolve to `Html`
You can insert blocks of Rust code in your HTML, as long as they resolve to `Html`

```rust
use yew::prelude::*;

let show_link = true;
fn some_computation() -> bool {
true
}

html! {
<div>
{
let show_link = some_computation();
if show_link {
html! {
<a href="https://example.com">{"Link"}</a>
Expand Down
2 changes: 1 addition & 1 deletion website/sidebars/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module.exports = {
'concepts/html/classes',
'concepts/html/fragments',
'concepts/html/lists',
'concepts/html/literals-and-expressions',
'concepts/html/literals-and-code-blocks',
'concepts/html/conditional-rendering',
],
},
Expand Down

0 comments on commit 0c43713

Please sign in to comment.