diff --git a/packages/yew-macro/src/html_tree/html_element.rs b/packages/yew-macro/src/html_tree/html_element.rs
index 408a260ab13..7991873b354 100644
--- a/packages/yew-macro/src/html_tree/html_element.rs
+++ b/packages/yew-macro/src/html_tree/html_element.rs
@@ -128,9 +128,9 @@ impl ToTokens for HtmlElement {
.as_ref()
.map(|attr| {
let value = &attr.value;
- quote_spanned! {value.span()=> #value}
+ quote! { ::std::option::Option::Some( #value ) }
})
- .unwrap_or(quote! { false });
+ .unwrap_or(quote! { ::std::option::Option::None });
// other attributes
diff --git a/packages/yew/src/dom_bundle/btag/attributes.rs b/packages/yew/src/dom_bundle/btag/attributes.rs
index 7cfa0a5224d..7731969cd46 100644
--- a/packages/yew/src/dom_bundle/btag/attributes.rs
+++ b/packages/yew/src/dom_bundle/btag/attributes.rs
@@ -67,18 +67,22 @@ impl Apply for InputFields {
type Element = InputElement;
fn apply(mut self, root: &BSubtree, el: &Self::Element) -> Self {
- // IMPORTANT! This parameter has to be set every time
+ // IMPORTANT! This parameter has to be set every time it's explicitly given
// to prevent strange behaviour in the browser when the DOM changes
- el.set_checked(self.checked);
+ if let Some(checked) = self.checked {
+ el.set_checked(checked);
+ }
self.value = self.value.apply(root, el);
self
}
fn apply_diff(self, root: &BSubtree, el: &Self::Element, bundle: &mut Self) {
- // IMPORTANT! This parameter has to be set every time
+ // IMPORTANT! This parameter has to be set every time it's explicitly given
// to prevent strange behaviour in the browser when the DOM changes
- el.set_checked(self.checked);
+ if let Some(checked) = self.checked {
+ el.set_checked(checked);
+ }
self.value.apply_diff(root, el, &mut bundle.value);
}
diff --git a/packages/yew/src/virtual_dom/vtag.rs b/packages/yew/src/virtual_dom/vtag.rs
index 4e4e5fc88f8..c54011d5765 100644
--- a/packages/yew/src/virtual_dom/vtag.rs
+++ b/packages/yew/src/virtual_dom/vtag.rs
@@ -62,7 +62,7 @@ pub(crate) struct InputFields {
/// It exists to override standard behavior of `checked` attribute, because
/// in original HTML it sets `defaultChecked` value of `InputElement`, but for reactive
/// frameworks it's more useful to control `checked` value of an `InputElement`.
- pub(crate) checked: bool,
+ pub(crate) checked: Option,
}
impl Deref for InputFields {
@@ -81,7 +81,7 @@ impl DerefMut for InputFields {
impl InputFields {
/// Crate new attributes for an [InputElement] element
- fn new(value: Option, checked: bool) -> Self {
+ fn new(value: Option, checked: Option) -> Self {
Self {
value: Value::new(value),
checked,
@@ -164,7 +164,7 @@ impl VTag {
#[allow(clippy::too_many_arguments)]
pub fn __new_input(
value: Option,
- checked: bool,
+ checked: Option,
node_ref: NodeRef,
key: Option,
// at bottom for more readable macro-expanded coded
@@ -341,20 +341,29 @@ impl VTag {
/// Returns `checked` property of an
/// [InputElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
- /// (Not a value of node's attribute).
- pub fn checked(&self) -> bool {
+ /// (Does not affect the value of the node's attribute).
+ pub fn checked(&self) -> Option {
match &self.inner {
VTagInner::Input(f) => f.checked,
- _ => false,
+ _ => None,
}
}
/// Sets `checked` property of an
/// [InputElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
- /// (Not a value of node's attribute).
+ /// (Does not affect the value of the node's attribute).
pub fn set_checked(&mut self, value: bool) {
if let VTagInner::Input(f) = &mut self.inner {
- f.checked = value;
+ f.checked = Some(value);
+ }
+ }
+
+ /// Keeps the current value of the `checked` property of an
+ /// [InputElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
+ /// (Does not affect the value of the node's attribute).
+ pub fn preserve_checked(&mut self) {
+ if let VTagInner::Input(f) = &mut self.inner {
+ f.checked = None;
}
}
@@ -479,7 +488,9 @@ mod feat_ssr {
write_attr(w, "value", Some(m));
}
- if self.checked() {
+ // Setting is as an attribute sets the `defaultChecked` property. Only emit this
+ // if it's explicitly set to checked.
+ if self.checked() == Some(true) {
write_attr(w, "checked", None);
}
}