54 lines
1.4 KiB
Swift
54 lines
1.4 KiB
Swift
import Elementary
|
|
|
|
/// The frame a page wraps its content in: a skip link, the ``SiteHeader``, the content inside `main`, and the ``SiteFooter``.
|
|
struct SiteLayout<Content: HTML>: HTML {
|
|
|
|
// MARK: Properties
|
|
|
|
/// The format marked as current in the header, or `nil` for none.
|
|
let active: Format?
|
|
|
|
/// The screen's markup, rendered inside the `main` landmark.
|
|
let content: Content
|
|
|
|
/// The signed-in viewer, or `nil` to render the signed-out header.
|
|
let viewer: Viewer?
|
|
|
|
// MARK: Initializers
|
|
|
|
/// Creates a site layout around a screen's content.
|
|
/// - Parameters:
|
|
/// - active: the format marked as current, or `nil` (the default) for none.
|
|
/// - viewer: the signed-in viewer, or `nil` (the default) to render the signed-out header.
|
|
/// - content: the screen's markup.
|
|
init(
|
|
active: Format? = nil,
|
|
viewer: Viewer? = nil,
|
|
@HTMLBuilder content: () -> Content
|
|
) {
|
|
self.active = active
|
|
self.content = content()
|
|
self.viewer = viewer
|
|
}
|
|
|
|
// MARK: Computed
|
|
|
|
var body: some HTML {
|
|
a(
|
|
.class("skip-link"),
|
|
.href("#main")
|
|
) {
|
|
"Skip to content"
|
|
}
|
|
SiteHeader(
|
|
active: active,
|
|
viewer: viewer
|
|
)
|
|
main(.id("main")) {
|
|
content
|
|
}
|
|
SiteFooter()
|
|
}
|
|
|
|
}
|