Allow DOMRenderer to render buttons with non-Text labels (#403) (#409)

Currently, `DOMRenderer` can only handle `Button`s where is the label is `Text`. If it is any other `View`, the `Button` is not rendered. This is the cause of #403.

This PR removes this restriction. Additionally, it expands the `ButtonStyle` demo to include `Button`s with complex labels.
This commit is contained in:
ezraberch 2021-06-07 12:17:43 -04:00 committed by GitHub
parent 44280847cf
commit da9843d07f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 23 deletions

View File

@ -18,9 +18,10 @@
import TokamakCore import TokamakCore
import TokamakStaticHTML import TokamakStaticHTML
extension _Button: ViewDeferredToRenderer where Label == Text { extension _Button: ViewDeferredToRenderer {
@_spi(TokamakCore) @_spi(TokamakCore)
public var deferredBody: AnyView { public var deferredBody: AnyView {
var attributes: [HTMLAttribute: String] = [:]
let listeners: [String: Listener] = [ let listeners: [String: Listener] = [
"pointerdown": { _ in isPressed = true }, "pointerdown": { _ in isPressed = true },
"pointerup": { _ in "pointerup": { _ in
@ -28,18 +29,12 @@ extension _Button: ViewDeferredToRenderer where Label == Text {
action() action()
}, },
] ]
if buttonStyle.type == DefaultButtonStyle.self { if buttonStyle.type != DefaultButtonStyle.self {
attributes["class"] = "_tokamak-buttonstyle-reset"
}
return AnyView(DynamicHTML( return AnyView(DynamicHTML(
"button", "button",
["class": "_tokamak-buttonstyle-default"], attributes,
listeners: listeners
) {
HTML("span", content: label.innerHTML(shouldSortAttributes: false) ?? "")
})
} else {
return AnyView(DynamicHTML(
"button",
["class": "_tokamak-buttonstyle-reset"],
listeners: listeners listeners: listeners
) { ) {
buttonStyle.makeBody( buttonStyle.makeBody(
@ -52,4 +47,3 @@ extension _Button: ViewDeferredToRenderer where Label == Text {
}) })
} }
} }
}

View File

@ -30,12 +30,41 @@ public struct ButtonStyleDemo: View {
Button("Default Style") { Button("Default Style") {
print("tapped") print("tapped")
} }
Button(action: { print("tapped") }, label: {
HStack {
Text("Default").padding(.trailing, 5)
Circle().frame(width: 10, height: 10, alignment: .center)
Text("Style").padding(.horizontal, 5)
Ellipse().fill(Color.red).frame(width: 20, height: 10, alignment: .center)
Text("With").padding(.horizontal, 5)
Capsule().fill(Color.green).frame(width: 20, height: 10, alignment: .center)
Text("Complex").padding(.horizontal, 5)
Rectangle().fill(Color.blue).frame(width: 10, height: 10, alignment: .center)
Text("Label").padding(.leading, 5)
}
})
Button("Pressed Button Style") { Button("Pressed Button Style") {
print("tapped") print("tapped")
} }
.buttonStyle( .buttonStyle(
PressedButtonStyle(pressedColor: Color.red) PressedButtonStyle(pressedColor: Color.red)
) )
Button(action: { print("tapped") }, label: {
HStack {
Text("Pressed").padding(.trailing, 5)
Circle().frame(width: 10, height: 10, alignment: .center)
Text("Style").padding(.horizontal, 5)
Ellipse().fill(Color.red).frame(width: 20, height: 10, alignment: .center)
Text("With").padding(.horizontal, 5)
Capsule().fill(Color.green).frame(width: 20, height: 10, alignment: .center)
Text("Complex").padding(.horizontal, 5)
Rectangle().fill(Color.blue).frame(width: 10, height: 10, alignment: .center)
Text("Label").padding(.leading, 5)
}
})
.buttonStyle(
PressedButtonStyle(pressedColor: Color.red)
)
} }
} }
} }