diff --git a/Cargo.toml b/Cargo.toml index 90647d3..b70005a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["web-component", "derive"] \ No newline at end of file +members = ["wasm-web-component", "macros"] \ No newline at end of file diff --git a/derive/Cargo.toml b/macros/Cargo.toml similarity index 90% rename from derive/Cargo.toml rename to macros/Cargo.toml index 543a3d6..efb74c5 100644 --- a/derive/Cargo.toml +++ b/macros/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "web-component-derive" +name = "wasm-web-component-macros" version = "0.1.0" edition = "2021" diff --git a/derive/src/lib.rs b/macros/src/lib.rs similarity index 94% rename from derive/src/lib.rs rename to macros/src/lib.rs index 4178f1a..94dea5c 100644 --- a/derive/src/lib.rs +++ b/macros/src/lib.rs @@ -11,7 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - use inflector::Inflector; use proc_macro::TokenStream; use proc_macro2::{Literal, Span}; @@ -80,7 +79,7 @@ fn expand_component_def( class_name: &Literal, element_name: &Literal, ) -> syn::ItemImpl { - let trait_path = expand_crate_ref("web-component-rs", parse_quote!(WebComponentDef)); + let trait_path = expand_crate_ref("wasm-web-component", parse_quote!(WebComponentDef)); parse_quote! { impl #trait_path for #struct_name { fn element_name() -> &'static str { @@ -96,8 +95,8 @@ fn expand_component_def( } fn expand_struct_trait_shim(struct_name: &Ident, observed_attrs: Literal) -> syn::ItemImpl { - let trait_path = expand_crate_ref("web-component-rs", parse_quote!(WebComponentDef)); - let handle_path = expand_crate_ref("web-component-rs", parse_quote!(WebComponentHandle)); + let trait_path = expand_crate_ref("wasm-web-component", parse_quote!(WebComponentDef)); + let handle_path = expand_crate_ref("wasm-web-component", parse_quote!(WebComponentHandle)); parse_quote! { impl #struct_name { pub fn element_name() -> &'static str { @@ -175,7 +174,7 @@ return element;", } fn expand_wasm_shim(struct_name: &Ident) -> syn::ItemImpl { - let trait_path = expand_crate_ref("web-component-rs", parse_quote!(WebComponentBinding)); + let trait_path = expand_crate_ref("wasm-web-component", parse_quote!(WebComponentBinding)); parse_quote! { #[wasm_bindgen::prelude::wasm_bindgen] impl #struct_name { @@ -229,7 +228,7 @@ fn expand_wasm_shim(struct_name: &Ident) -> syn::ItemImpl { } fn expand_binding(struct_name: &Ident) -> syn::ItemImpl { - let trait_path = expand_crate_ref("web-component-rs", parse_quote!(WebComponent)); + let trait_path = expand_crate_ref("wasm-web-component", parse_quote!(WebComponent)); parse_quote!( impl #trait_path for #struct_name {} ) @@ -259,6 +258,7 @@ fn expand_struct( TokenStream::from(expanded) } +/// Creates the necessary Rust and Javascript shims for a Web Component. #[proc_macro_attribute] pub fn web_component(attr: TokenStream, item: TokenStream) -> TokenStream { // TODO(jwall): Attrs for class name and element name diff --git a/web-component/Cargo.lock b/wasm-web-component/Cargo.lock similarity index 100% rename from web-component/Cargo.lock rename to wasm-web-component/Cargo.lock diff --git a/web-component/Cargo.toml b/wasm-web-component/Cargo.toml similarity index 90% rename from web-component/Cargo.toml rename to wasm-web-component/Cargo.toml index 002ca28..c75671b 100644 --- a/web-component/Cargo.toml +++ b/wasm-web-component/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "web-component-rs" +name = "wasm-web-component" version = "0.1.0" edition = "2021" author = "Jeremy Wall " @@ -10,7 +10,7 @@ crate-type = ["cdylib", "rlib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -web-component-derive = {path = "../derive"} +wasm-web-component-macros = { path = "../macros" } [dependencies.wasm-bindgen-test] version = "0.3" diff --git a/web-component/src/lib.rs b/wasm-web-component/src/lib.rs similarity index 76% rename from web-component/src/lib.rs rename to wasm-web-component/src/lib.rs index 48533f4..80eeccb 100644 --- a/web-component/src/lib.rs +++ b/wasm-web-component/src/lib.rs @@ -2,8 +2,25 @@ use js_sys::Function; use wasm_bindgen::{convert::IntoWasmAbi, prelude::Closure, JsValue}; use web_sys::{window, Element, HtmlElement}; -pub mod macros; +/// This attribute proc-macro will generate the following trait implementations +/// * [WebComponentDef](trait@WebComponentDef) +/// * [WebComponent](trait@WebComponent) +/// +/// It will also generate a wasm_bindgen compatible impl block for your struct. +/// +/// It expects you to implement the [WebComponentBinding](trait@WebComponentBinding) +/// trait in order to implement the callbacks. +/// +/// It supports three attribute `name = value` parameters. +/// * `class_name = "ClassName"` - Required. The class name to use for the javascript shim. +/// * `element_name = "class-name"` - Optional. A valid custom element name to use for the element. +/// * `observed_attrs = "['attr1', attr2']"` - Optional. A javascript array with a list of observed attributes for this compoment. +/// +/// Reference [MDN Web Components Guide](https://developer.mozilla.org/en-US/docs/Web/Web_Components) +pub use wasm_web_component_macros::web_component; +/// Helper trait for Rust Web Components. This is autogenerated +/// by the [`#[web_component]`](wasm_web_component_macros::web_component) attribute. pub trait WebComponentDef: IntoWasmAbi + Default { fn new() -> Self { Self::default() @@ -22,6 +39,9 @@ pub trait WebComponentDef: IntoWasmAbi + Default { fn class_name() -> &'static str; } +/// Trait defining the lifecycle callbacks for a Custom Element. +/// Each method is optional. You only need to implement the ones +/// you want to specify behavior for. pub trait WebComponentBinding: WebComponentDef { fn connected(&self, _element: &HtmlElement) { // noop @@ -46,11 +66,18 @@ pub trait WebComponentBinding: WebComponentDef { } } +/// Marker trait used in the generated shims to assert that their are Rust implemtntations +/// of the callback functions for the component. pub trait WebComponent: WebComponentBinding {} -// TODO(jwall): Trait methods can't be exported out to js yet so we'll need a wrapper object or we'll need to `Derive` this api in a prop-macro. +/// A handle for your WebComponent Definition. It is important that this +/// handle is live for as long as your Web-Component might be used. pub struct WebComponentHandle { + /// The handle for the closure that is used to construct your Rust instance + /// in the Javascript shim constructor. If this is dropped then your web component + /// will not be able to be constructed properly. pub impl_handle: Closure T>, + /// A javascript function that can construct your element. pub element_constructor: Function, } @@ -63,7 +90,7 @@ mod tests { use web_sys::Text; use web_sys::{window, HtmlElement}; - use web_component_derive::web_component; + use wasm_web_component_macros::web_component; wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); diff --git a/web-component/src/macros.rs b/web-component/src/macros.rs deleted file mode 100644 index 8068d9e..0000000 --- a/web-component/src/macros.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2022 Jeremy Wall (Jeremy@marzhilsltudios.com) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License.