Skip to content

Commit ea14a3f

Browse files
committed
Add onclick support to Button.
1 parent 4fbe98a commit ea14a3f

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

Sources/Slipstream/W3C/Elements/Forms/Button.swift

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,46 @@ import SwiftSoup
44
///
55
/// - SeeAlso: W3C [button](https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element) specification.
66
@available(iOS 17.0, macOS 14.0, *)
7-
public struct Button<Content>: View where Content: View {
7+
public struct Button<Label>: View where Label: View {
8+
/// Creates a button that displays a custom label and executes a custom action
9+
/// when clicked.
10+
public init(action: String, @ViewBuilder label: @escaping () -> Label) {
11+
self.label = label
12+
self.action = action
13+
}
14+
815
/// Creates a button that displays a custom label.
9-
public init(@ViewBuilder content: @escaping () -> Content) {
10-
self.content = content
16+
public init(@ViewBuilder label: @escaping () -> Label) {
17+
self.label = label
18+
self.action = nil
1119
}
1220

1321
/// Creates a button that generates its label from a string.
14-
public init(_ text: String) where Content == DOMString {
15-
self.content = {
22+
public init(_ text: String) where Label == DOMString {
23+
self.label = {
1624
DOMString(text)
1725
}
26+
self.action = nil
1827
}
1928

20-
@_documentation(visibility: private)
21-
@ViewBuilder public let content: () -> Content
29+
/// Creates a button that generates its label from a string and executes a custom
30+
/// action when clicked.
31+
public init(_ text: String, action: String) where Label == DOMString {
32+
self.label = {
33+
DOMString(text)
34+
}
35+
self.action = action
36+
}
37+
38+
@ViewBuilder private let label: () -> Label
39+
private let action: String?
2240

2341
@_documentation(visibility: private)
2442
public func render(_ container: Element, environment: EnvironmentValues) throws {
2543
let element = try container.appendElement("button")
26-
try self.content().render(element, environment: environment)
44+
if let action {
45+
try element.attr("onclick", action)
46+
}
47+
try self.label().render(element, environment: environment)
2748
}
2849
}

Tests/SlipstreamTests/W3C/Forms/ButtonTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,19 @@ struct ButtonTests {
66
@Test func emptyBlock() throws {
77
try #expect(renderHTML(Button {}) == "<button></button>")
88
}
9+
910
@Test func withText() throws {
1011
try #expect(renderHTML(Button("Tap me")) == #"<button>Tap me</button>"#)
1112
}
1213

14+
@Test func withAction() throws {
15+
try #expect(renderHTML(Button(action: "alert('hello world')") {
16+
DOMString("Tap me")
17+
}) == #"<button onclick="alert('hello world')">Tap me</button>"#)
18+
19+
try #expect(renderHTML(Button("Tap me", action: "alert('hello world')")) == #"<button onclick="alert('hello world')">Tap me</button>"#)
20+
}
21+
1322
@Test func withCustomContent() throws {
1423
try #expect(renderHTML(Button {
1524
Text("Tap me")

0 commit comments

Comments
 (0)