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>

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
Github: johanmattssonm
Linkedin: johan-mattsson-2ab324112