Skip to content

Commit

Permalink
Add Stylesheet implementation.
Browse files Browse the repository at this point in the history
Part of #25.
  • Loading branch information
jverkoey committed Aug 3, 2024
1 parent c7c6f73 commit c0c9a8e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
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

- <doc:Head>
- <doc:Title>
- <doc:Stylesheet>
- <doc:Meta>
- <doc:Charset>
- <doc:Viewport>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@ import Foundation
import SwiftSoup

/// A view that represents various kinds of metadata that cannot be expressed
/// using the ``Title``, ``Base``, ``Link``, ``Style``, and ``Script`` views.
/// using the ``Title``, ``Base``, ``Stylesheet``, ``Style``, and ``Script`` views.
///
/// ```swift
/// struct MySiteMetadata: View {
/// var body: some View {
/// Head {
/// Meta(.description, content: "My cool site")
/// }
/// }
/// }
/// ```
///
/// - SeeAlso: W3C [`meta charset`](https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element) specification.
/// - SeeAlso: WHATWG [meta extensions](https://wiki.whatwg.org/wiki/MetaExtensions).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation

import SwiftSoup

/// A view that causes a stylesheet to be imported when the page is loaded
///
/// ```swift
/// struct MySiteMetadata: View {
/// var body: some View {
/// Head {
/// Stylesheet("My awesome site")
/// }
/// }
/// }
/// ```
///
/// - SeeAlso: W3C [`link`](https://html.spec.whatwg.org/multipage/semantics.html#the-link-element) specification.
@available(iOS 17.0, macOS 14.0, *)
public struct Stylesheet: View {
/// Creates a Stylesheet view.
public init(_ url: URL?) {
self.url = url
}

@_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", "stylesheet")
try element.attr("href", url.absoluteString)
}

private let url: URL?
}
5 changes: 4 additions & 1 deletion Tests/SlipstreamTests/Sites/CatalogSiteTests.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Foundation
import Testing

import Slipstream
Expand All @@ -10,7 +11,8 @@ private struct CatalogSite: View {
Charset(.utf8)
Title("Build websites with Swift and Tailwind CSS — Slipstream")
Viewport.mobileFriendly
Meta("description", content: "Slipstream is a static website generator built in the Swift programming language and compatible with Tailwind CSS.")
Meta(.description, content: "Slipstream is a static website generator built in the Swift programming language and compatible with Tailwind CSS.")
Stylesheet(URL(string: "/css/bootstrap.css"))
}
Body {
Text("Hello, world!")
Expand All @@ -28,6 +30,7 @@ struct CatalogSiteTests {
<title>Build websites with Swift and Tailwind CSS — Slipstream</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Slipstream is a static website generator built in the Swift programming language and compatible with Tailwind CSS." />
<link rel="stylesheet" href="/css/bootstrap.css" />
</head>
<body>
Hello, world!
Expand Down
14 changes: 14 additions & 0 deletions Tests/SlipstreamTests/Views/W3C/StylesheetTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import Testing

import Slipstream

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

@Test func validURL() throws {
try #expect(renderHTML(Stylesheet(URL(string: "/main.css"))) == #"<link rel="stylesheet" href="/main.css" />"#)
}
}

0 comments on commit c0c9a8e

Please sign in to comment.