Skip to content

Commit

Permalink
Add onclick support to Button. (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
jverkoey authored Aug 10, 2024
1 parent 4fbe98a commit 335439c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
37 changes: 29 additions & 8 deletions Sources/Slipstream/W3C/Elements/Forms/Button.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,46 @@ import SwiftSoup
///
/// - SeeAlso: W3C [button](https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element) specification.
@available(iOS 17.0, macOS 14.0, *)
public struct Button<Content>: View where Content: View {
public struct Button<Label>: View where Label: View {
/// Creates a button that displays a custom label and executes a custom action
/// when clicked.
public init(action: String, @ViewBuilder label: @escaping () -> Label) {
self.label = label
self.action = action
}

/// Creates a button that displays a custom label.
public init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
public init(@ViewBuilder label: @escaping () -> Label) {
self.label = label
self.action = nil
}

/// Creates a button that generates its label from a string.
public init(_ text: String) where Content == DOMString {
self.content = {
public init(_ text: String) where Label == DOMString {
self.label = {
DOMString(text)
}
self.action = nil
}

@_documentation(visibility: private)
@ViewBuilder public let content: () -> Content
/// Creates a button that generates its label from a string and executes a custom
/// action when clicked.
public init(_ text: String, action: String) where Label == DOMString {
self.label = {
DOMString(text)
}
self.action = action
}

@ViewBuilder private let label: () -> Label
private let action: String?

@_documentation(visibility: private)
public func render(_ container: Element, environment: EnvironmentValues) throws {
let element = try container.appendElement("button")
try self.content().render(element, environment: environment)
if let action {
try element.attr("onclick", action)
}
try self.label().render(element, environment: environment)
}
}
9 changes: 9 additions & 0 deletions Tests/SlipstreamTests/W3C/Forms/ButtonTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ struct ButtonTests {
@Test func emptyBlock() throws {
try #expect(renderHTML(Button {}) == "<button></button>")
}

@Test func withText() throws {
try #expect(renderHTML(Button("Tap me")) == #"<button>Tap me</button>"#)
}

@Test func withAction() throws {
try #expect(renderHTML(Button(action: "alert('hello world')") {
DOMString("Tap me")
}) == #"<button onclick="alert('hello world')">Tap me</button>"#)

try #expect(renderHTML(Button("Tap me", action: "alert('hello world')")) == #"<button onclick="alert('hello world')">Tap me</button>"#)
}

@Test func withCustomContent() throws {
try #expect(renderHTML(Button {
Text("Tap me")
Expand Down

0 comments on commit 335439c

Please sign in to comment.