diff --git a/wasm-web-component/src/lib.rs b/wasm-web-component/src/lib.rs index e108181..1671827 100644 --- a/wasm-web-component/src/lib.rs +++ b/wasm-web-component/src/lib.rs @@ -18,9 +18,103 @@ use web_sys::{window, Element, Event, HtmlElement, Window}; /// * `element_name = "class-name"` - A valid custom element name to use for the element. if not proviced derives it from the class name. /// * `observed_attrs = "['attr1', attr2']"` - A javascript array with a list of observed attributes for this compoment. Defaults to "[]". /// +/// It will also create a `Self::define_once` method that will define the WebComponent exactly +/// once. +/// +/// ## Example +/// +/// ```rust +/// #[web_component( +/// class_name = "MyElement", +/// element_name = "my-element", +/// observed_attrs = "['class']" +/// )] +/// pub struct MyElementImpl {} +/// +/// impl WebComponentBinding for MyElementImpl { +/// fn connected(&self, element: &HtmlElement) { +/// let node = Text::new().unwrap(); +/// node.set_text_content(Some("Added a text node on connect".into())); +/// element.append_child(&node).unwrap(); +/// } +/// +/// fn disconnected(&self, element: &HtmlElement) { +/// let node = element.first_child().unwrap(); +/// element.remove_child(&node).unwrap(); +/// } +/// +/// fn adopted(&self, element: &HtmlElement) { +/// let node = Text::new().unwrap(); +/// node.set_text_content(Some("Added a text node on adopt".into())); +/// element.append_child(&node).unwrap(); +/// } +/// +/// fn attribute_changed( +/// &self, +/// element: &HtmlElement, +/// name: JsValue, +/// old_value: JsValue, +/// new_value: JsValue, +/// ) { +/// let node = element.first_child().unwrap(); +/// node.set_text_content(Some(&format!( +/// "Setting {} from {} to {}", +/// name.as_string().unwrap_or("None".to_owned()), +/// old_value.as_string().unwrap_or("None".to_owned()), +/// new_value.as_string().unwrap_or("None".to_owned()), +/// ))); +/// element.append_child(&node).unwrap(); +/// } +/// } +/// +/// pub fn define_me() { +/// MyElementImpl::define_once(); +/// } +/// ``` /// Reference [MDN Web Components Guide](https://developer.mozilla.org/en-US/docs/Web/Web_Components) pub use wasm_web_component_macros::web_component; +/// This attribute proc-macro will generate the following trait implementation +/// [TemplateElement](trait@TemplateElement) +/// +/// It will also generate a wasm_bindgen compatible impl block for your struct. It expects +/// you to implement [TemplateElementRender](trait@TemplateElementRender) trait in order to +/// allow it to implement the methods using methods from that trait. +/// +/// You can define the template element exactly once by calling the `Self::define_once` method. +/// Subsequent calls to that method will be a noop. It returns one of the following values: +/// * `Some(None)` If the template doesn't have an id. +/// * `Some(Some(id))` If the template has an id. +/// * `None` Should never get returned. +/// +/// A `get_id` method will also get defined for you that returns the same values with the difference that +/// if the template has not been defined yet `None` will get returned. +/// +/// ## Example usage +/// ```rust +/// #[template_element] +/// pub struct MyTemplate (); +/// impl TemplateElementRender for MyTemplate { +/// fn render() -> HtmlTemplateElement { +/// let val: JsValue = window() +/// .unwrap() +/// .document() +/// .unwrap() +/// .create_element("template") +/// .unwrap() +/// .into(); +/// let el: HtmlTemplateElement = val.into(); +/// el.set_attribute("id", "template-id").unwrap(); +/// return el; +/// } +/// } +/// +/// pub fn define_it() { +/// let id: Option<&'static Option> = MyTemplate::define_once(); +/// } +/// ``` +pub use wasm_web_component_macros::template_element; + /// Helper trait for Rust Web Components. This is autogenerated /// by the [`#[web_component]`](web_component) attribute. pub trait WebComponentDef: IntoWasmAbi + Default {