Merge branch 'main' into typed-event-handlers
This commit is contained in:
commit
19d7b8434b
|
@ -70,11 +70,12 @@ features = [
|
|||
]
|
||||
|
||||
[dev-dependencies]
|
||||
leptos = { path = "../leptos", default-features = false, version = "0.0" }
|
||||
leptos_macro = { path = "../leptos_macro", default-features = false, version = "0.0" }
|
||||
|
||||
|
||||
[features]
|
||||
csr = ["leptos_reactive/csr", "leptos_macro/csr"]
|
||||
hydrate = ["leptos_reactive/hydrate", "leptos_macro/hydrate"]
|
||||
ssr = ["leptos_reactive/ssr", "leptos_macro/ssr"]
|
||||
stable = ["leptos_reactive/stable", "leptos_macro/stable"]
|
||||
csr = ["leptos_reactive/csr", "leptos_macro/csr", "leptos/csr"]
|
||||
hydrate = ["leptos_reactive/hydrate", "leptos_macro/hydrate", "leptos/hydrate"]
|
||||
ssr = ["leptos_reactive/ssr", "leptos_macro/ssr", "leptos/ssr"]
|
||||
stable = ["leptos_reactive/stable", "leptos_macro/stable", "leptos/stable"]
|
||||
|
|
|
@ -140,3 +140,15 @@ macro_rules! is_dev {
|
|||
cfg!(debug_assertions)
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn __leptos_renderer_error(expected: &'static str, location: &'static str) -> web_sys::Node {
|
||||
cfg_if! {
|
||||
if #[cfg(debug_assertions)] {
|
||||
panic!("Yikes! Something went wrong while Leptos was trying to traverse the DOM to set up the reactive system.\n\nThe renderer expected {expected:?} as {location} and couldn't get it.\n\nThis is almost certainly a bug in the framework, not your application. Please open an issue on GitHub and provide example code if possible.\n\nIn the meantime, these bugs are often related to <Component/>s or {{block}}s when they are siblings of each other. Try wrapping those in a <span> or <div> for now. Sorry for the pain!")
|
||||
} else {
|
||||
_ = expected;
|
||||
panic!("Renderer error. You can find a more detailed error message if you compile in debug mode.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,6 +244,60 @@ pub fn view(tokens: TokenStream) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
/// Annotates a function so that it can be used with your template as a <Component/>
|
||||
///
|
||||
/// Here are some things you should know.
|
||||
/// 1. The component name should be `CamelCase` instead of `snake_case`. This is how the renderer
|
||||
/// recognizes that a particular tag is a component, not an HTML element.
|
||||
///
|
||||
/// ```
|
||||
/// # use leptos::*;
|
||||
/// // ❌ not snake_case
|
||||
/// #[component]
|
||||
/// fn my_component(cx: Scope) -> Element { todo!() }
|
||||
///
|
||||
/// // ✅ CamelCase
|
||||
/// #[component]
|
||||
/// fn MyComponent(cx: Scope) -> Element { todo!() }
|
||||
/// ```
|
||||
///
|
||||
/// 2. The macro generates a type `ComponentProps` for every `Component` (so, `HomePage` generates `HomePageProps`,
|
||||
/// `Button` generates `ButtonProps`, etc.) When you’re importing the component, you also need to **explicitly import
|
||||
/// the prop type.**
|
||||
///
|
||||
/// ```
|
||||
/// # use leptos::*;
|
||||
///
|
||||
/// use component::{MyComponent, MyComponentProps};
|
||||
///
|
||||
/// mod component {
|
||||
/// use leptos::*;
|
||||
///
|
||||
/// #[component]
|
||||
/// pub fn MyComponent(cx: Scope) -> Element { todo!() }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// 3. You can pass generic arguments, but they should be defined in a `where` clause and not inline.
|
||||
///
|
||||
/// ```compile_error
|
||||
/// # use leptos::*;
|
||||
/// #[component]
|
||||
/// fn MyComponent<T: Fn() -> Element>(cx: Scope, render_prop: T) -> Element {
|
||||
/// todo!()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use leptos::*;
|
||||
/// #[component]
|
||||
/// fn MyComponent<T>(cx: Scope, render_prop: T) -> Element
|
||||
/// where
|
||||
/// T: Fn() -> Element,
|
||||
/// {
|
||||
/// todo!()
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn component(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
||||
match syn::parse::<component::InlinePropsBody>(s) {
|
||||
|
|
|
@ -383,14 +383,14 @@ fn element_to_tokens(
|
|||
quote_spanned! {
|
||||
span => let #this_el_ident = #debug_name;
|
||||
//log::debug!("next_sibling ({})", #debug_name);
|
||||
let #this_el_ident = #prev_sib.next_sibling().unwrap_throw();
|
||||
let #this_el_ident = #prev_sib.next_sibling().unwrap_or_else(|| ::leptos::__leptos_renderer_error(#debug_name, "nextSibling"));
|
||||
//log::debug!("=> got {}", #this_el_ident.node_name());
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {
|
||||
span => let #this_el_ident = #debug_name;
|
||||
//log::debug!("first_child ({})", #debug_name);
|
||||
let #this_el_ident = #parent.first_child().unwrap_throw();
|
||||
let #this_el_ident = #parent.first_child().unwrap_or_else(|| ::leptos::__leptos_renderer_error(#debug_name, "firstChild"));
|
||||
//log::debug!("=> got {}", #this_el_ident.node_name());
|
||||
}
|
||||
};
|
||||
|
@ -816,13 +816,13 @@ fn block_to_tokens(
|
|||
let location = if let Some(sibling) = &prev_sib {
|
||||
quote_spanned! {
|
||||
span => //log::debug!("-> next sibling");
|
||||
let #name = #sibling.next_sibling().unwrap_throw();
|
||||
let #name = #sibling.next_sibling().unwrap_or_else(|| ::leptos::__leptos_renderer_error("{block}", "nextSibling"));
|
||||
//log::debug!("\tnext sibling = {}", #name.node_name());
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {
|
||||
span => //log::debug!("\\|/ first child on {}", #parent.node_name());
|
||||
let #name = #parent.first_child().unwrap_throw();
|
||||
let #name = #parent.first_child().unwrap_or_else(|| ::leptos::__leptos_renderer_error("{block}", "firstChild"));
|
||||
//log::debug!("\tfirst child = {}", #name.node_name());
|
||||
}
|
||||
};
|
||||
|
@ -938,6 +938,8 @@ fn component_to_tokens(
|
|||
mode: Mode,
|
||||
is_first_child: bool,
|
||||
) -> PrevSibChange {
|
||||
let component_name = ident_from_tag_name(&node.name);
|
||||
let component_name = format!("<{component_name}/>");
|
||||
let create_component = create_component(cx, node, mode);
|
||||
let span = node.name.span();
|
||||
|
||||
|
@ -974,13 +976,13 @@ fn component_to_tokens(
|
|||
let starts_at = if let Some(prev_sib) = prev_sib {
|
||||
quote::quote! {{
|
||||
//log::debug!("starts_at = next_sibling");
|
||||
#prev_sib.next_sibling().unwrap_throw()
|
||||
#prev_sib.next_sibling().unwrap_or_else(|| ::leptos::__leptos_renderer_error(#component_name, "nextSibling"))
|
||||
//log::debug!("ok starts_at");
|
||||
}}
|
||||
} else {
|
||||
quote::quote! {{
|
||||
//log::debug!("starts_at first_child");
|
||||
#parent.first_child().unwrap_throw()
|
||||
#parent.first_child().unwrap_or_else(|| ::leptos::__leptos_renderer_error(#component_name, "firstChild"))
|
||||
//log::debug!("starts_at ok");
|
||||
}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue