Skip to content

Commit

Permalink
Add Icon. (#184)
Browse files Browse the repository at this point in the history
Part of #25.
  • Loading branch information
jverkoey authored Sep 14, 2024
1 parent d061eb9 commit 4dc0a98
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ provided below is an organized table of W3C HTML tags and their equivalent Slips
[`<link rel="expect">`](https://html.spec.whatwg.org/multipage/links.html#link-type-expect) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="external">`](https://html.spec.whatwg.org/multipage/links.html#link-type-external) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="help">`](https://html.spec.whatwg.org/multipage/links.html#link-type-help) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="icon">`](https://html.spec.whatwg.org/multipage/links.html#rel-icon) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="icon">`](https://html.spec.whatwg.org/multipage/links.html#rel-icon) | ``Icon``
[`<link rel="manifest">`](https://html.spec.whatwg.org/multipage/links.html#link-type-manifest) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="modulepreload">`](https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<link rel="license">`](https://html.spec.whatwg.org/multipage/links.html#link-type-license) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
Expand Down
1 change: 1 addition & 0 deletions Sources/Slipstream/Documentation.docc/W3C/W3CViews.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The complete W3C HTML elements standard can be found [here](https://html.spec.wh

- ``Head``
- ``Title``
- ``Icon``
- ``Preload``
- ``Preconnect``
- ``Stylesheet``
Expand Down
51 changes: 51 additions & 0 deletions Sources/Slipstream/W3C/Elements/DocumentMetadata/Icon.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Foundation

import SwiftSoup

/// A view that is an icon representing the page or site/.
///
/// ```swift
/// struct MySiteMetadata: View {
/// var body: some View {
/// Head {
/// Icon(URL(string: "/favicon.ico"))
/// }
/// }
/// }
/// ```
///
/// - SeeAlso: W3C [rel="icon"](https://html.spec.whatwg.org/multipage/links.html#rel-icon) specification.
@available(iOS 17.0, macOS 14.0, *)
public struct Icon: View {
/// Creates an Icon view.
///
/// - Parameters:
/// - url: The icon will be loaded from this URL.
/// - sizes: Gives the sizes of icons for visual media. If present, is only advisory.
/// - type: The MIME type of the linked resource. If present, is only advisory and must be a valid MIME type.
public init(_ url: URL?, sizes: String? = nil, type: String? = nil) {
self.url = url
self.sizes = sizes
self.type = type
}

@_documentation(visibility: private)
public func render(_ container: Element, environment: EnvironmentValues) throws {
guard let url else {
return
}
let element = try container.appendElement("link")
try element.attr("rel", "icon")
try element.attr("href", url.absoluteString)
if let sizes {
try element.attr("sizes", sizes)
}
if let type {
try element.attr("type", type)
}
}

private let url: URL?
private let sizes: String?
private let type: String?
}
22 changes: 22 additions & 0 deletions Tests/SlipstreamTests/W3C/IconTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation
import Testing

import Slipstream

struct IconTests {
@Test func nilURL() throws {
try #expect(renderHTML(Icon(nil)) == "")
}

@Test func validURL() throws {
try #expect(renderHTML(Icon(URL(string: "/favicon.ico"))) == #"<link rel="icon" href="/favicon.ico" />"#)
}

@Test func sizes() throws {
try #expect(renderHTML(Icon(URL(string: "/favicon.ico"), sizes: "16x16")) == #"<link rel="icon" href="/favicon.ico" sizes="16x16" />"#)
}

@Test func type() throws {
try #expect(renderHTML(Icon(URL(string: "/favicon.ico"), type: "image/png")) == #"<link rel="icon" href="/favicon.ico" type="image/png" />"#)
}
}

0 comments on commit 4dc0a98

Please sign in to comment.