Fix update of `checked` property of checkbox input (#309)

Resolve #287.

The `checked` attribute is a peculiar one, as any value on it keeps the checkbox checked. Attribute updates in `DOMRenderer` don't handle removals of attributes, but this seems to be the only case where this is relevant. I've added special handling for this attribute and checkbox inputs, and also had to declare `HTMLAttribute.checked` to set `isUpdatedAsProperty: true` on it for it to fully work.
This commit is contained in:
Max Desiatov 2020-11-28 11:27:18 +00:00 committed by GitHub
parent c754b313ef
commit dfcacc862f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 1 deletions

View File

@ -24,12 +24,25 @@ extension AnyHTML {
// @carson-katri: For diffing, could you build a Set from the keys and values of the dictionary,
// then use the standard lib to get the difference?
// `checked` attribute on checkboxes is a special one as its value doesn't matter. We only
// need to check whether it exists or not, and set the property if it doesn't.
var containsChecked = false
for (attribute, value) in attributes {
if attribute.isUpdatedAsProperty {
dom.ref[dynamicMember: attribute.value] = .string(value)
} else {
_ = dom.ref.setAttribute!(attribute.value, value)
}
if attribute == .checked {
containsChecked = true
}
}
if !containsChecked && dom.ref.type == "checkbox" &&
dom.ref.tagName.string!.lowercased == "input"
{
dom.ref.checked = .boolean(false)
}
if let dynamicSelf = self as? AnyDynamicHTML {

View File

@ -30,7 +30,7 @@ public struct CheckboxToggleStyle: ToggleStyle {
public func makeBody(configuration: ToggleStyleConfiguration) -> some View {
var attrs: [HTMLAttribute: String] = ["type": "checkbox"]
if configuration.isOn {
attrs["checked"] = "checked"
attrs[.checked] = "checked"
}
return HTML("label") {
DynamicHTML("input", attrs, listeners: [

View File

@ -32,6 +32,8 @@ public struct HTMLAttribute: Hashable {
}
public static let value = HTMLAttribute("value", isUpdatedAsProperty: true)
public static let checked = HTMLAttribute("checked", isUpdatedAsProperty: true)
}
extension HTMLAttribute: CustomStringConvertible {