Skip to content

Commit

Permalink
Added ability to use multiple classes in view macro using array syntax.
Browse files Browse the repository at this point in the history
  • Loading branch information
bicarlsen committed Apr 16, 2024
1 parent e29d31e commit 9df416f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 28 deletions.
19 changes: 12 additions & 7 deletions leptos_macro/src/view/client_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,19 @@ fn attr_to_tokens(
// Classes
else if let Some(name) = name.strip_prefix("class:") {
let value = attribute_value(node);
match value {
syn::Expr::Lit(value) => {
todo!();
}

expressions.push(quote_spanned! {
span=> ::leptos::leptos_dom::class_helper(
::leptos::wasm_bindgen::JsCast::unchecked_ref(&#el_id),
#name.into(),
::leptos::IntoClass::into_class(#value),
)
});
_ => expressions.push(quote_spanned! {
span=> ::leptos::leptos_dom::class_helper(
::leptos::wasm_bindgen::JsCast::unchecked_ref(&#el_id),
#name.into(),
::leptos::IntoClass::into_class(#value),
)
}),
};
}
// Attributes
else {
Expand Down
91 changes: 70 additions & 21 deletions leptos_macro/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use convert_case::{Case::Snake, Casing};
use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::{quote, quote_spanned};
use rstml::node::{KeyedAttribute, Node, NodeElement, NodeName};
use syn::{spanned::Spanned, Expr, Expr::Tuple, ExprLit, ExprPath, Lit};
use syn::{
spanned::Spanned,
Expr::{self, Tuple},
ExprArray, ExprLit, ExprPath, Lit,
};

pub mod client_builder;
pub mod client_template;
Expand Down Expand Up @@ -404,27 +408,72 @@ fn fancy_class_name<'a>(
node.key.span()=> .class
};
let class_name = &tuple.elems[0];
let class_name = if let Expr::Lit(ExprLit {
lit: Lit::Str(s),
..
}) = class_name
{
s.value()
} else {
proc_macro_error::emit_error!(
class_name.span(),
"class name must be a string literal"
);
Default::default()
};
let value = &tuple.elems[1];
return Some((
quote! {
#class(#class_name, #value)
},
class_name,
value,
));

match class_name {
Expr::Lit(ExprLit {
lit: Lit::Str(s), ..
}) => {
let class_name = s.value();
return Some((
quote! {
#class(#class_name, #value)
},
class_name,
value,
));
}

Expr::Array(ExprArray { elems, .. }) => {
let (tokens, class_name): (Vec<_>, Vec<_>) = elems
.iter()
.map(|elem| match elem {
Expr::Lit(ExprLit {
lit: Lit::Str(s), ..
}) => {
let class_name = s.value();
let tokens = quote! {
#class(#class_name, #value)
};
(tokens, class_name)
}

_ => {
proc_macro_error::emit_error!(
elem.span(),
"class name elements must be string \
literals"
);

(TokenStream::new(), Default::default())
}
})
.unzip();

let class_name = class_name.join(" ");
return Some((
quote! { #(#tokens)*},
class_name,
value,
));
}

_ => {
proc_macro_error::emit_error!(
class_name.span(),
"class name must be a string literal or array of \
string literals"
);
let class_name = Default::default();
return Some((
quote! {
#class(#class_name, #value)
},
class_name,
value,
));
}
}
} else {
proc_macro_error::emit_error!(
tuple.span(),
Expand Down

0 comments on commit 9df416f

Please sign in to comment.