-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lay foundation for a statically typed vdom #2396
Conversation
Visit the preview URL for this PR (updated for commit 3ee3b94): https://yew-rs--pr2396-typed-vdom-foundatio-2dnyy8kt.web.app (expires Tue, 15 Mar 2022 14:07:48 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
It clashes with export of html! macro and it's basically never used in code anyway
Marking this as draft because I'll need to solve this at the macro level somehow, not by creating hundreds of components. I ran twiggy the diff shows the size is increased by the components (which is fair):
|
832cfba
to
06d4bd8
Compare
I'm unsubscribing for now but please let me know when you have interesting updates or you need a review! |
What if this strictly typed dom would only be used to typecheck the declared |
This PR became a thing because of my other (properties) PR. I had the code ready to get components to be built so I did it. At the moment, the thing that is preventing this to move forward is the While writing this comment, I got the idea of using a function instead of putting the checks in the component code. I'll try that soon |
# Conflicts: # packages/yew-router/src/components/link.rs # packages/yew/src/virtual_dom/vlist.rs # packages/yew/src/virtual_dom/vportal.rs # packages/yew/src/virtual_dom/vtag.rs
Does anyone know why these tests are failing: https://github.com/yewstack/yew/runs/5465453730?check_suite_focus=true The failures seem to be coming out of bundle_dom tests. @WorldSEnder can you have a look? |
My guess is that ref-handling is different when using components vs using |
This is basically what the generated code looks like: impl ::yew::Component for #element_name {
type Message = ();
type Properties = #props_ident;
fn create(_ctx: &::yew::html::Context<Self>) -> Self {
Self
}
fn view(&self, ctx: &::yew::html::Context<Self>) -> ::yew::html::Html {
#[allow(unused_mut)]
let mut element = ctx.props().clone().into_data();
::std::convert::Into::<::yew::virtual_dom::VNode>::into({
::yew::virtual_dom::VTag::__new_other(
::std::stringify!(#element_name).into(),
element.node_ref,
element.key,
::yew::virtual_dom::Attributes::IndexMap(element.attributes.into_iter().collect()),
::yew::virtual_dom::Listeners::Pending(element.listeners.into_boxed_slice()),
::yew::virtual_dom::VList::with_children(element.children, ::std::option::Option::None),
)
})
}
} Props have this node_ref: #[prop_or_default]
pub node_ref: ::std::option::Option::<::yew::NodeRef>, Props get converted into data like so: impl #props_ident {
fn into_data(self) -> ::yew::virtual_dom::typings::ElementData {
::yew::virtual_dom::typings::ElementData {
node_ref: ::std::option::Option::unwrap_or_default(self.node_ref.clone()),
attributes: {
let mut attrs = ::std::collections::HashMap::new();
#(#attr_if_lets)*
attrs
},
listeners: {
let mut listeners = ::std::vec![];
#(#listeners_if_lets)*
listeners
},
key: self.key.clone(),
children: self.children.into_iter().collect(),
}
}
} I'm not sure how the adding a component could change the behavior of node ref. This is what the generated code looks like:#[allow(non_camel_case_types)]
pub struct button;
#[derive(::std::default::Default, ::std::clone::Clone, ::std::fmt::Debug, ::yew::html::Properties, ::std::cmp::PartialEq)]
pub struct ButtonProps {
#[prop_or_default] pub __globals: ::yew::virtual_dom::typings::globals::Globals,
#[prop_or_default] pub node_ref: ::std::option::Option::<::yew::NodeRef>,
#[prop_or_default] pub key: ::std::option::Option::<::yew::virtual_dom::Key>,
#[prop_or_default] pub children: ::yew::Children,
#[prop_or_default] pub r#autofocus: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#disabled: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#form: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#formaction: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#formenctype: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#formmethod: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#formnovalidate: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#formtarget: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#name: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#type: ::std::option::Option::<AttrValue>,
#[prop_or_default] pub r#value: ::std::option::Option::<AttrValue>,
}
impl std::ops::Deref for ButtonProps {
type Target = ::yew::virtual_dom::typings::globals::Globals;
fn deref(&self) -> &Self::Target { &self.__globals }
}
impl std::ops::DerefMut for ButtonProps { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.__globals } }
impl ButtonProps {
fn into_data(self) -> ::yew::virtual_dom::typings::ElementData {
::yew::virtual_dom::typings::ElementData {
node_ref: ::std::option::Option::unwrap_or_default(self.node_ref.clone()),
attributes: {
let mut attrs = ::std::collections::HashMap::new();
if let ::std::option::Option::Some(val) = self.r#autocapitalize.as_ref() { attrs.insert("autocapitalize", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#contextmenu.as_ref() { attrs.insert("contextmenu", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#contenteditable.as_ref() { attrs.insert("contenteditable", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#slot.as_ref() { attrs.insert("slot", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#spellcheck.as_ref() { attrs.insert("spellcheck", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#class.as_ref() { attrs.insert("class", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#title.as_ref() { attrs.insert("title", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#itemprop.as_ref() { attrs.insert("itemprop", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#accesskey.as_ref() { attrs.insert("accesskey", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#lang.as_ref() { attrs.insert("lang", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#id.as_ref() { attrs.insert("id", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#translate.as_ref() { attrs.insert("translate", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#draggable.as_ref() { attrs.insert("draggable", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#style.as_ref() { attrs.insert("style", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#dir.as_ref() { attrs.insert("dir", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#tabindex.as_ref() { attrs.insert("tabindex", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#hidden.as_ref() { attrs.insert("hidden", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_atomic.as_ref() { attrs.insert("aria-atomic", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_invalid.as_ref() { attrs.insert("aria-invalid", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_rowcount.as_ref() { attrs.insert("aria-rowcount", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_colindex.as_ref() { attrs.insert("aria-colindex", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_grabbed.as_ref() { attrs.insert("aria-grabbed", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_hidden.as_ref() { attrs.insert("aria-hidden", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_details.as_ref() { attrs.insert("aria-details", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_owns.as_ref() { attrs.insert("aria-owns", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_placeholder.as_ref() { attrs.insert("aria-placeholder", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_required.as_ref() { attrs.insert("aria-required", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_selected.as_ref() { attrs.insert("aria-selected", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_sort.as_ref() { attrs.insert("aria-sort", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_activedescendant.as_ref() { attrs.insert("aria-activedescendant", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_autocomplete.as_ref() { attrs.insert("aria-autocomplete", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_keyshortcuts.as_ref() { attrs.insert("aria-keyshortcuts", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_live.as_ref() { attrs.insert("aria-live", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_valuemax.as_ref() { attrs.insert("aria-valuemax", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_current.as_ref() { attrs.insert("aria-current", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_labelledby.as_ref() { attrs.insert("aria-labelledby", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_colcount.as_ref() { attrs.insert("aria-colcount", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_setsize.as_ref() { attrs.insert("aria-setsize", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_readonly.as_ref() { attrs.insert("aria-readonly", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_valuetext.as_ref() { attrs.insert("aria-valuetext", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_disabled.as_ref() { attrs.insert("aria-disabled", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_pressed.as_ref() { attrs.insert("aria-pressed", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_haspopup.as_ref() { attrs.insert("aria-haspopup", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_valuenow.as_ref() { attrs.insert("aria-valuenow", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_relevant.as_ref() { attrs.insert("aria-relevant", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_description.as_ref() { attrs.insert("aria-description", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_busy.as_ref() { attrs.insert("aria-busy", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_multiselectable.as_ref() { attrs.insert("aria-multiselectable", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_expanded.as_ref() { attrs.insert("aria-expanded", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_level.as_ref() { attrs.insert("aria-level", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_describedby.as_ref() { attrs.insert("aria-describedby", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_rowindex.as_ref() { attrs.insert("aria-rowindex", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_errormessage.as_ref() { attrs.insert("aria-errormessage", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_flowto.as_ref() { attrs.insert("aria-flowto", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_dropeffect.as_ref() { attrs.insert("aria-dropeffect", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_multiline.as_ref() { attrs.insert("aria-multiline", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_modal.as_ref() { attrs.insert("aria-modal", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_label.as_ref() { attrs.insert("aria-label", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_controls.as_ref() { attrs.insert("aria-controls", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_checked.as_ref() { attrs.insert("aria-checked", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_orientation.as_ref() { attrs.insert("aria-orientation", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_roledescription.as_ref() { attrs.insert("aria-roledescription", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_posinset.as_ref() { attrs.insert("aria-posinset", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_valuemin.as_ref() { attrs.insert("aria-valuemin", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_rowspan.as_ref() { attrs.insert("aria-rowspan", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#aria_colspan.as_ref() { attrs.insert("aria-colspan", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#role.as_ref() { attrs.insert("role", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#autofocus.as_ref() { attrs.insert("autofocus", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#disabled.as_ref() { attrs.insert("disabled", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#form.as_ref() { attrs.insert("form", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#formaction.as_ref() { attrs.insert("formaction", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#formenctype.as_ref() { attrs.insert("formenctype", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#formmethod.as_ref() { attrs.insert("formmethod", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#formnovalidate.as_ref() { attrs.insert("formnovalidate", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#formtarget.as_ref() { attrs.insert("formtarget", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#name.as_ref() { attrs.insert("name", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#type.as_ref() { attrs.insert("type", val.clone()); }
if let ::std::option::Option::Some(val) = self.r#value.as_ref() { attrs.insert("value", val.clone()); }
attrs
},
listeners: {
let mut listeners = (::alloc::vec::Vec::new());
if let Some(value) = self.onabort.as_ref() { listeners.push(::yew::html::onabort::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncancel.as_ref() { listeners.push(::yew::html::oncancel::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncanplay.as_ref() { listeners.push(::yew::html::oncanplay::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncanplaythrough.as_ref() { listeners.push(::yew::html::oncanplaythrough::Wrapper::__macro_new(value)); }
if let Some(value) = self.onclose.as_ref() { listeners.push(::yew::html::onclose::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncuechange.as_ref() { listeners.push(::yew::html::oncuechange::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondurationchange.as_ref() { listeners.push(::yew::html::ondurationchange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onemptied.as_ref() { listeners.push(::yew::html::onemptied::Wrapper::__macro_new(value)); }
if let Some(value) = self.onended.as_ref() { listeners.push(::yew::html::onended::Wrapper::__macro_new(value)); }
if let Some(value) = self.onerror.as_ref() { listeners.push(::yew::html::onerror::Wrapper::__macro_new(value)); }
if let Some(value) = self.onformdata.as_ref() { listeners.push(::yew::html::onformdata::Wrapper::__macro_new(value)); }
if let Some(value) = self.oninvalid.as_ref() { listeners.push(::yew::html::oninvalid::Wrapper::__macro_new(value)); }
if let Some(value) = self.onload.as_ref() { listeners.push(::yew::html::onload::Wrapper::__macro_new(value)); }
if let Some(value) = self.onloadeddata.as_ref() { listeners.push(::yew::html::onloadeddata::Wrapper::__macro_new(value)); }
if let Some(value) = self.onloadedmetadata.as_ref() { listeners.push(::yew::html::onloadedmetadata::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpause.as_ref() { listeners.push(::yew::html::onpause::Wrapper::__macro_new(value)); }
if let Some(value) = self.onplay.as_ref() { listeners.push(::yew::html::onplay::Wrapper::__macro_new(value)); }
if let Some(value) = self.onplaying.as_ref() { listeners.push(::yew::html::onplaying::Wrapper::__macro_new(value)); }
if let Some(value) = self.onratechange.as_ref() { listeners.push(::yew::html::onratechange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onreset.as_ref() { listeners.push(::yew::html::onreset::Wrapper::__macro_new(value)); }
if let Some(value) = self.onresize.as_ref() { listeners.push(::yew::html::onresize::Wrapper::__macro_new(value)); }
if let Some(value) = self.onsecuritypolicyviolation.as_ref() { listeners.push(::yew::html::onsecuritypolicyviolation::Wrapper::__macro_new(value)); }
if let Some(value) = self.onseeked.as_ref() { listeners.push(::yew::html::onseeked::Wrapper::__macro_new(value)); }
if let Some(value) = self.onseeking.as_ref() { listeners.push(::yew::html::onseeking::Wrapper::__macro_new(value)); }
if let Some(value) = self.onselect.as_ref() { listeners.push(::yew::html::onselect::Wrapper::__macro_new(value)); }
if let Some(value) = self.onslotchange.as_ref() { listeners.push(::yew::html::onslotchange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onstalled.as_ref() { listeners.push(::yew::html::onstalled::Wrapper::__macro_new(value)); }
if let Some(value) = self.onsuspend.as_ref() { listeners.push(::yew::html::onsuspend::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontimeupdate.as_ref() { listeners.push(::yew::html::ontimeupdate::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontoggle.as_ref() { listeners.push(::yew::html::ontoggle::Wrapper::__macro_new(value)); }
if let Some(value) = self.onvolumechange.as_ref() { listeners.push(::yew::html::onvolumechange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onwaiting.as_ref() { listeners.push(::yew::html::onwaiting::Wrapper::__macro_new(value)); }
if let Some(value) = self.onchange.as_ref() { listeners.push(::yew::html::onchange::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncopy.as_ref() { listeners.push(::yew::html::oncopy::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncut.as_ref() { listeners.push(::yew::html::oncut::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpaste.as_ref() { listeners.push(::yew::html::onpaste::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerlockchange.as_ref() { listeners.push(::yew::html::onpointerlockchange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerlockerror.as_ref() { listeners.push(::yew::html::onpointerlockerror::Wrapper::__macro_new(value)); }
if let Some(value) = self.onselectionchange.as_ref() { listeners.push(::yew::html::onselectionchange::Wrapper::__macro_new(value)); }
if let Some(value) = self.onselectstart.as_ref() { listeners.push(::yew::html::onselectstart::Wrapper::__macro_new(value)); }
if let Some(value) = self.onshow.as_ref() { listeners.push(::yew::html::onshow::Wrapper::__macro_new(value)); }
if let Some(value) = self.onauxclick.as_ref() { listeners.push(::yew::html::onauxclick::Wrapper::__macro_new(value)); }
if let Some(value) = self.onclick.as_ref() { listeners.push(::yew::html::onclick::Wrapper::__macro_new(value)); }
if let Some(value) = self.oncontextmenu.as_ref() { listeners.push(::yew::html::oncontextmenu::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondblclick.as_ref() { listeners.push(::yew::html::ondblclick::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondrag.as_ref() { listeners.push(::yew::html::ondrag::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragend.as_ref() { listeners.push(::yew::html::ondragend::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragenter.as_ref() { listeners.push(::yew::html::ondragenter::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragexit.as_ref() { listeners.push(::yew::html::ondragexit::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragleave.as_ref() { listeners.push(::yew::html::ondragleave::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragover.as_ref() { listeners.push(::yew::html::ondragover::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondragstart.as_ref() { listeners.push(::yew::html::ondragstart::Wrapper::__macro_new(value)); }
if let Some(value) = self.ondrop.as_ref() { listeners.push(::yew::html::ondrop::Wrapper::__macro_new(value)); }
if let Some(value) = self.onblur.as_ref() { listeners.push(::yew::html::onblur::Wrapper::__macro_new(value)); }
if let Some(value) = self.onfocus.as_ref() { listeners.push(::yew::html::onfocus::Wrapper::__macro_new(value)); }
if let Some(value) = self.onfocusin.as_ref() { listeners.push(::yew::html::onfocusin::Wrapper::__macro_new(value)); }
if let Some(value) = self.onfocusout.as_ref() { listeners.push(::yew::html::onfocusout::Wrapper::__macro_new(value)); }
if let Some(value) = self.onkeydown.as_ref() { listeners.push(::yew::html::onkeydown::Wrapper::__macro_new(value)); }
if let Some(value) = self.onkeypress.as_ref() { listeners.push(::yew::html::onkeypress::Wrapper::__macro_new(value)); }
if let Some(value) = self.onkeyup.as_ref() { listeners.push(::yew::html::onkeyup::Wrapper::__macro_new(value)); }
if let Some(value) = self.onloadstart.as_ref() { listeners.push(::yew::html::onloadstart::Wrapper::__macro_new(value)); }
if let Some(value) = self.onprogress.as_ref() { listeners.push(::yew::html::onprogress::Wrapper::__macro_new(value)); }
if let Some(value) = self.onloadend.as_ref() { listeners.push(::yew::html::onloadend::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmousedown.as_ref() { listeners.push(::yew::html::onmousedown::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmouseenter.as_ref() { listeners.push(::yew::html::onmouseenter::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmouseleave.as_ref() { listeners.push(::yew::html::onmouseleave::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmousemove.as_ref() { listeners.push(::yew::html::onmousemove::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmouseout.as_ref() { listeners.push(::yew::html::onmouseout::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmouseover.as_ref() { listeners.push(::yew::html::onmouseover::Wrapper::__macro_new(value)); }
if let Some(value) = self.onmouseup.as_ref() { listeners.push(::yew::html::onmouseup::Wrapper::__macro_new(value)); }
if let Some(value) = self.onwheel.as_ref() { listeners.push(::yew::html::onwheel::Wrapper::__macro_new(value)); }
if let Some(value) = self.oninput.as_ref() { listeners.push(::yew::html::oninput::Wrapper::__macro_new(value)); }
if let Some(value) = self.onsubmit.as_ref() { listeners.push(::yew::html::onsubmit::Wrapper::__macro_new(value)); }
if let Some(value) = self.onanimationcancel.as_ref() { listeners.push(::yew::html::onanimationcancel::Wrapper::__macro_new(value)); }
if let Some(value) = self.onanimationend.as_ref() { listeners.push(::yew::html::onanimationend::Wrapper::__macro_new(value)); }
if let Some(value) = self.onanimationiteration.as_ref() { listeners.push(::yew::html::onanimationiteration::Wrapper::__macro_new(value)); }
if let Some(value) = self.onanimationstart.as_ref() { listeners.push(::yew::html::onanimationstart::Wrapper::__macro_new(value)); }
if let Some(value) = self.ongotpointercapture.as_ref() { listeners.push(::yew::html::ongotpointercapture::Wrapper::__macro_new(value)); }
if let Some(value) = self.onlostpointercapture.as_ref() { listeners.push(::yew::html::onlostpointercapture::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointercancel.as_ref() { listeners.push(::yew::html::onpointercancel::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerdown.as_ref() { listeners.push(::yew::html::onpointerdown::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerenter.as_ref() { listeners.push(::yew::html::onpointerenter::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerleave.as_ref() { listeners.push(::yew::html::onpointerleave::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointermove.as_ref() { listeners.push(::yew::html::onpointermove::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerout.as_ref() { listeners.push(::yew::html::onpointerout::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerover.as_ref() { listeners.push(::yew::html::onpointerover::Wrapper::__macro_new(value)); }
if let Some(value) = self.onpointerup.as_ref() { listeners.push(::yew::html::onpointerup::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontouchcancel.as_ref() { listeners.push(::yew::html::ontouchcancel::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontouchend.as_ref() { listeners.push(::yew::html::ontouchend::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontransitioncancel.as_ref() { listeners.push(::yew::html::ontransitioncancel::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontransitionend.as_ref() { listeners.push(::yew::html::ontransitionend::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontransitionrun.as_ref() { listeners.push(::yew::html::ontransitionrun::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontransitionstart.as_ref() { listeners.push(::yew::html::ontransitionstart::Wrapper::__macro_new(value)); }
if let Some(value) = self.onscroll.as_ref() { listeners.push(::yew::html::onscroll::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontouchmove.as_ref() { listeners.push(::yew::html::ontouchmove::Wrapper::__macro_new(value)); }
if let Some(value) = self.ontouchstart.as_ref() { listeners.push(::yew::html::ontouchstart::Wrapper::__macro_new(value)); }
listeners
},
key: self.key.clone(),
children: self.children.into_iter().collect(),
}
}
}
impl ::yew::Component for button {
type Message = ();
type Properties = ButtonProps;
fn create(_ctx: &::yew::html::Context<Self>) -> Self { Self }
fn view(&self, ctx: &::yew::html::Context<Self>) -> ::yew::html::Html {
#[allow(unused_mut)] let mut element = ctx.props().clone().into_data();
::std::convert::Into::<::yew::virtual_dom::VNode>::into({ ::yew::virtual_dom::VTag::__new_other(::std::stringify!(button ).into(), element.node_ref, element.key, ::yew::virtual_dom::Attributes::IndexMap(element.attributes.into_iter().collect()), ::yew::virtual_dom::Listeners::Pending(element.listeners.into_boxed_slice()), ::yew::virtual_dom::VList::with_children(element.children, ::std::option::Option::None)) })
}
} Unrelated side note: any suggestions on how to reduce the |
I'm a bit confused if the ref is being translated into a ref on the generated component, or if it's actually being set on the properties. I.e. in the end we have yew/packages/yew-macro/src/html_tree/html_component.rs Lines 148 to 149 in 3ee3b94
but the Props also include a field called So if I have <a ref={foo} />
// Equivalent to
<::yew::virtual_dom::typings::a node_ref={foo} /> right? |
Oh that's confusing. I didn't know component's could have their refs too. I wonder which one is set |
Worst case, both are set. That would probably confuse the internals the most. |
I doubt both are set since props can't be duplicated and i think special_props take priority internally |
I'm closing this as this implementation should not be used. We have to look at a different way to implementing this in the future |
Description
Pulls useful code from #2369
The implementation generates components for each HTML element using a new macro,
generate_element!
. Every attribute and listener is passed as props to the component. The component'sview
method creates aVTag
based on the passed data,Special casing for
textarea
inVTag
has also been removed. Previously, we usedvalue
attribute ontextarea
, which is not part of standard. See MDN docs:Limitations
Right now, there are some limitations (to be resolved in the future):
data
attributes not yet supported with static typing.html!
macroWorkaround
These limitations can be bypassed by opting out of static typing. This is done by using dynamic tags.
Checklist
I have runCI passescargo make pr-flow