This commit is contained in:
2024-12-05 07:50:55 -05:00
parent b0b218e047
commit 33356d8648
16 changed files with 216 additions and 146 deletions

View File

@@ -0,0 +1,11 @@
/// An empty text node.
public struct Empty: TextNode {
@inlinable
public init() {}
@inlinable
public var body: some TextNode {
""
}
}

View File

@@ -0,0 +1,16 @@
public struct Group<Content: TextNode>: TextNode {
@usableFromInline
var content: Content
@inlinable
public init(
@TextBuilder content: () -> Content
) {
self.content = content()
}
@inlinable
public var body: some TextNode {
content
}
}

View File

@@ -0,0 +1,23 @@
public struct HStack: TextNode {
@usableFromInline
let content: [any TextNode]
@usableFromInline
let separator: any TextNode
@inlinable
public init(
spacing: Int = 1,
@TextBuilder content: () -> any TextNode
) {
self.content = array(from: content())
self.separator = seperator(" ", count: spacing > 0 ? spacing - 1 : 0)
}
@inlinable
public var body: some TextNode {
content.removingEmptys()
.joined(separator: separator.render())
}
}

View File

@@ -0,0 +1,46 @@
public struct Section<Header: TextNode, Content: TextNode, Footer: TextNode>: TextNode {
@usableFromInline
let header: Header
@usableFromInline
let content: Content
@usableFromInline
let footer: Footer
@inlinable
public init(
@TextBuilder header: () -> Header,
@TextBuilder content: () -> Content,
@TextBuilder footer: () -> Footer
) {
self.header = header()
self.content = content()
self.footer = footer()
}
public var body: some TextNode {
style(.default)
}
}
public extension Section where Footer == Empty {
@inlinable
init(
@TextBuilder header: () -> Header,
@TextBuilder content: () -> Content
) {
self.init(header: header, content: content) { Empty() }
}
}
public extension Section where Header == Empty {
@inlinable
init(
@TextBuilder content: () -> Content,
@TextBuilder footer: () -> Footer
) {
self.init(header: { Empty() }, content: content, footer: footer)
}
}

View File

@@ -0,0 +1,23 @@
public struct VStack: TextNode {
@usableFromInline
let content: [any TextNode]
@usableFromInline
let separator: any TextNode
@inlinable
public init(
spacing: Int = 1,
@TextBuilder content: () -> any TextNode
) {
self.content = array(from: content())
self.separator = seperator("\n", count: spacing > 0 ? spacing - 1 : 0)
}
@inlinable
public var body: some TextNode {
content.removingEmptys()
.joined(separator: separator.render())
}
}