Kaja Web Components
Full Example: main-component
Node Example: Node Module
Reusability
The developer can combine Kaja components with ordinary HTML, CSS, and JavaScript. No need to make the whole application follow one component architecture.
For example, components can be combined like this:
<main-component>
<h1>Hello!<h1>
<counter-component></counter-component>
<timer-component></timer-component>
</main-component>
Getting Started
Install the required dependencies:
cargo add kaja-web
cargo add kaja-html-macro
cargo add kaja-callback-macro
cargo add kaja-web-component
cargo add wasm-bindgen
cargo add inventory
cargo add web-sys
cargo add gloo
cargo add js-sys
cargo add console_error_panic_hook
Component
use kaja_web::prelude::*;
#[component("main-component")]
struct Main {
#[attribute]
test: bool,
}
The #[component] macro defines a custom HTML element,
named main-component in this example.
The #[attribute] macro associates the
test field with an HTML attribute.
Attributes can be updated with JavaScript:
document
.querySelector("main-component")
.setAttribute("test", "true");
or in HTML:
<main-component test="true"></main-component>
or in Rust:
for element in get_elements("main-component") {
let _ = element.set_attribute("test", "true");
}
Implementation
The macro generates a new empty impl called
MainComponent, different from Main
but with access to the same functionality.
use kaja_web::prelude::*;
impl Component for MainComponent {
fn connected(&self) {
log!("Connected:", self.get_id());
}
fn disconnected(&self) {
log!("Disconnected:", self.get_id());
}
fn attribute_changed(
&self,
name: &str,
_old_value: &str,
_new_value: &str
) {
if name == "test" {
self.render();
}
}
}
Rendering
Rendering can be done in attribute_changed
but it is a separate function in this example.
use kaja_web::prelude::*;
impl MainComponent {
fn render(&self) {
let test: bool = self.get_attribute("test").unwrap_or_default();
let content = html! {{
<p>Test: $test</p>
}};
let id = self.get_id();
if let Some(element) = get_element_by_id(&id) {
element.set_inner_html(content.as_str());
} else {
error!("Element not found for component id:", id);
}
}
}
Startup
use kaja_web::prelude::*;
#[wasm_bindgen(start)]
pub fn init() {
let elements = get_elements("main-component");
for element in elements {
let id = element.id();
if id.is_empty() {
continue;
}
if let Some(element) = get_element_by_id(&id) {
let test = true;
let _ = element.set_attribute("test", test.to_string().as_str());
}
}
}
Usage
<main-component test="false"></main-component>