mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 14:54:16 +00:00
docs: add docs for #[island]
macro (#1691)
This commit is contained in:
parent
1c2327b2d6
commit
651356a9ec
3 changed files with 72 additions and 9 deletions
|
@ -10,7 +10,6 @@ readme = "../README.md"
|
|||
|
||||
[dependencies]
|
||||
cfg-if = "1"
|
||||
const_format = "0.2"
|
||||
leptos_dom = { workspace = true }
|
||||
leptos_macro = { workspace = true }
|
||||
leptos_reactive = { workspace = true }
|
||||
|
@ -24,7 +23,6 @@ serde_json = { version = "1", optional = true }
|
|||
server_fn = { workspace = true }
|
||||
web-sys = { version = "0.3.63", optional = true }
|
||||
wasm-bindgen = { version = "0.2", optional = true }
|
||||
xxhash-rust = "0.8"
|
||||
|
||||
[features]
|
||||
default = ["serde"]
|
||||
|
|
|
@ -204,9 +204,7 @@ pub use suspense_component::*;
|
|||
mod suspense_component;
|
||||
mod text_prop;
|
||||
mod transition;
|
||||
// used by the component macro to generate islands
|
||||
#[doc(hidden)]
|
||||
pub use const_format;
|
||||
|
||||
pub use text_prop::TextProp;
|
||||
#[cfg(any(debug_assertions, feature = "ssr"))]
|
||||
#[doc(hidden)]
|
||||
|
@ -232,9 +230,6 @@ pub use wasm_bindgen; // used in islands
|
|||
feature = "template_macro"
|
||||
))]
|
||||
pub use web_sys; // used in islands
|
||||
// used by the component macro to generate islands
|
||||
#[doc(hidden)]
|
||||
pub use xxhash_rust;
|
||||
mod children;
|
||||
pub use children::*;
|
||||
extern crate self as leptos;
|
||||
|
|
|
@ -631,7 +631,77 @@ pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
|||
.into()
|
||||
}
|
||||
|
||||
/// TODO docs for islands
|
||||
/// Defines a component as an interactive island when you are using the
|
||||
/// `experimental-islands` feature of Leptos. Apart from the macro name,
|
||||
/// the API is the same as the [`component`](macro@component) macro.
|
||||
///
|
||||
/// When you activate the `experimental-islands` feature, every `#[component]`
|
||||
/// is server-only by default. This "default to server" behavior is important:
|
||||
/// you opt into shipping code to the client, rather than opting out. You can
|
||||
/// opt into client-side interactivity for any given component by changing from
|
||||
/// `#[component]` to `#[island]`—the two macros are otherwise identical.
|
||||
///
|
||||
/// Everything that is included inside an island will be compiled to WASM and
|
||||
/// shipped to the browser. So the key to really benefiting from this architecture
|
||||
/// is to make islands as small as possible, and include only the minimal
|
||||
/// required amount of functionality in islands themselves.
|
||||
///
|
||||
/// Only code included in an island itself is compiled to WASM. This means:
|
||||
/// 1. `children` can be provided from a server `#[component]` to an `#[island]`
|
||||
/// without the island needing to be able to hydrate them.
|
||||
/// 2. Props can be passed from the server to an island.
|
||||
///
|
||||
/// ## Present Limitations
|
||||
/// A few noteworthy limitations, at the moment:
|
||||
/// 1. `children` are completely opaque in islands. You can't iterate over `children`;
|
||||
/// in fact they're all bundled into a single `<leptos-children>` HTML element.
|
||||
/// 2. Similarly, `children` need to be used in the HTML rendered on the server.
|
||||
/// If they need to be displayed conditionally, they should be included in the HTML
|
||||
/// and rendered or not using `display: none` rather than `<Show>` or ordinary control flow.
|
||||
/// This is because the children aren't serialized at all, other than as HTML: if that
|
||||
/// HTML isn't present in the DOM, even if hidden, it is never sent and not available
|
||||
/// to the client at all.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```rust,ignore
|
||||
/// use leptos::*;
|
||||
///
|
||||
/// #[component]
|
||||
/// pub fn App() -> impl IntoView {
|
||||
/// // this would panic if it ran in the browser
|
||||
/// // but because this isn't an island, it only runs on the server
|
||||
/// let file =
|
||||
/// std::fs::read_to_string("./src/is_this_a_server_component.txt")
|
||||
/// .unwrap();
|
||||
/// let len = file.len();
|
||||
///
|
||||
/// view! {
|
||||
/// <p>"The starting value for the button is the file's length."</p>
|
||||
/// // `value` is serialized and given to the island as a prop
|
||||
/// <Island value=len>
|
||||
/// // `file` is only available on the server
|
||||
/// // island props are projected in, so we can nest
|
||||
/// // server-only content inside islands inside server content etc.
|
||||
/// <p>{file}</p>
|
||||
/// </Island>
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[island]
|
||||
/// pub fn Island(
|
||||
/// #[prop(into)] value: RwSignal<usize>,
|
||||
/// children: Children,
|
||||
/// ) -> impl IntoView {
|
||||
/// // because `RwSignal<T>` implements `From<T>`, we can pass in a plain
|
||||
/// // value and use it as the starting value of a signal here
|
||||
/// view! {
|
||||
/// <button on:click=move |_| value.update(|n| *n += 1)>
|
||||
/// {value}
|
||||
/// </button>
|
||||
/// {children()}
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_error::proc_macro_error]
|
||||
#[proc_macro_attribute]
|
||||
pub fn island(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
||||
|
|
Loading…
Reference in a new issue