1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Leptos islands for Autumn apps: Leptos 0.8 components (wasm) inside
//! Maud + htmx pages.
//!
//! 1. Write the components in a wasm crate. Register them with
//! `autumn-plugin-leptos-client` in the start function:
//!
//! ```rust,ignore
//! use autumn_plugin_leptos_client::register;
//! use leptos::prelude::*;
//! use wasm_bindgen::prelude::*;
//!
//! #[wasm_bindgen(start)]
//! pub fn start() {
//! register("Counter", counter);
//! }
//! ```
//!
//! 2. Build it with `cargo build --target wasm32-unknown-unknown` and
//! `wasm-bindgen --target web`. Embed the output as a `PluginAssets`
//! bundle and install it:
//!
//! ```rust,no_run
//! use autumn_plugin_leptos::{Island, LeptosPlugin, leptos_bundle, leptos_script};
//! use autumn_web::assets::PluginAssets;
//! use autumn_web::prelude::*;
//!
//! static ISLANDS: PluginAssets = PluginAssets::from_files(
//! "app-islands",
//! &[("app.js", b"/* glue */"), ("app_bg.wasm", b"\0asm\x01\0\0\0")],
//! );
//!
//! #[get("/")]
//! async fn index() -> AutumnResult<Markup> {
//! let counter = Island::new("Counter")
//! .props(&serde_json::json!({ "start": 3 }))?
//! .fallback(html! { p { "Count: 3" } });
//! Ok(html! {
//! html {
//! head { (leptos_script()) (leptos_bundle(&ISLANDS)) }
//! body { (counter) }
//! }
//! })
//! }
//!
//! # async fn run() {
//! autumn_web::app()
//! .plugin(LeptosPlugin::new().bundle(&ISLANDS))
//! .routes(routes![index])
//! .run()
//! .await;
//! # }
//! ```
//!
//! 3. Set a CSP that allows wasm: [`WasmCspLoader`] or [`wasm_csp()`].
//!
//! The loader (`leptos-islands.js`) imports each bundle and mounts each
//! island. It mounts islands that htmx swaps in and unmounts islands that
//! htmx swaps out. A `data-leptos-props` change sets the props signal of
//! the same instance, so the component keeps its state. It uses no inline
//! script and no `eval`.
//!
//! # Features
//!
//! - `ssr`: [`Island::fallback_view`] renders a Leptos view on the server
//! as the fallback.
//!
//! # Security
//!
//! The loader mounts each `data-leptos-island` element in the page and
//! imports each accepted bundle link. If your app shows user HTML, the
//! sanitizer must remove `data-leptos-*`, `hx-*` and `data-hx-*`
//! attributes and `<link>` and `<template>` elements. `data-leptos-ignore`
//! does not give full protection. An htmx out-of-band swap can move an
//! element out of it.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;