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'sviewmethod creates aVTagbased on the passed data,Special casing for
textareainVTaghas also been removed. Previously, we usedvalueattribute ontextarea, which is not part of standard. See MDN docs:Limitations
Right now, there are some limitations (to be resolved in the future):
dataattributes 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