custom_element/
lib.rs

1#![deny(missing_docs)]
2
3//! # About custom-element
4//!
5//! `custom-element` provides a `CustomElement` trait that, when implemented,
6//! allows your Rust struct to be rendered as a web component on any html page.
7//!
8//! Web components are a great way to [eliminate frontend framework lock-in](https://jakelazaroff.com/words/web-components-eliminate-javascript-framework-lock-in/).
9//! They are also a great way to bridge the divide between UI components written in JavaScript
10//! and UI elements written in Rust.
11//!
12//! # Learn By Example
13//! If you want to see some examples of writing web components in Rust, check out
14//! [examples](https://github.com/austintheriot/custom-element/tree/main/examples) directory:
15//! - [`hello_world`](https://github.com/austintheriot/custom-element/tree/main/examples/hello_world) is the most basic web component you can create
16//! - [`counter`](https://github.com/austintheriot/custom-element/tree/main/examples/counter) is the standard
17//! counter example, showing how to re-render in response to events in pure Rust.
18//! - [`leptos_in_react`](https://github.com/austintheriot/custom-element/tree/main/examples/leptos_in_react)
19//! shows how you can mix Rust and JavaScript in the same codebase, and even mix Rust/JavaScript
20//! frameworks.
21//!
22//! # A Simple Hello World
23//!
24//! ```rust
25//! # use custom_element::CustomElement;
26//! # use js_sys::Array;
27//! # use wasm_bindgen::JsValue;
28//! # use web_sys::HtmlElement;
29//! #
30//! # // can't run web code in the docs
31//! # if false {
32//! #
33//! struct HelloWorld;
34//!
35//! // all custom element lifecycle hooks have a default no-op implementation
36//! impl CustomElement for HelloWorld {}
37//!
38//! impl HelloWorld {
39//!     // called from the JavaScript custom element's `constructor`
40//!     fn new(instance: JsValue, _args: Array) -> Self {
41//!         let instance: HtmlElement = instance.into();
42//!         instance.set_text_content(Some("Hello, world!"));
43//!         HelloWorld
44//!     }
45//! }
46//!
47//! fn main() {
48//!     // create custom element constructor
49//!     let component_name = "hello-world";
50//!     let (closure, constructor) = custom_element::create_custom_element(HelloWorld::new, vec![]);
51//!
52//!     // we want the Rust code for our custom element to live forever
53//!     closure.forget();
54//!
55//!     // define the element
56//!     let window = web_sys::window().unwrap();
57//!     window
58//!         .custom_elements()
59//!         .define(component_name, &constructor)
60//!         .unwrap();
61//!
62//!     // render in the DOM
63//!     let body = window.document().unwrap().body().unwrap();
64//!     body.set_inner_html(&format!("<{0}></{0}>", component_name));
65//! }
66//! # }
67//! ```
68
69mod bridge;
70mod create_custom_element;
71mod custom_element;
72mod generated_constructor;
73mod html_constructors;
74
75pub use bridge::*;
76pub use create_custom_element::*;
77pub use custom_element::*;
78pub use generated_constructor::*;
79pub use html_constructors::*;