Files
swift-cli-doc/Sources/CliDocCore/Nodes/VStack.swift
Michael Housh 78a632c3e5
All checks were successful
CI / Run tests. (push) Successful in 52s
feat: Adds more documentation and examples.
2024-12-08 18:27:31 -05:00

99 lines
2.4 KiB
Swift

/// A vertical stack of text nodes.
///
/// ### Example:
///
/// ```swift
/// let vStack = VStack {
/// "Blob Esquire"
/// .color(.yellow)
/// .bold()
/// .underline()
///
/// "Blob is a super awesome worker.".italic()
/// }
///
/// print(vStack.render())
/// ```
/// ![VStack rendered output](vstack.png)
///
///
public struct VStack: TextNode {
@usableFromInline
let content: [any TextNode]
/// Create a new ``VStack`` with the given text nodes.
///
/// - Parameters:
/// - content: The content of the vstack.
@inlinable
public init(
@TextBuilder content: () -> any TextNode
) {
self.content = array(from: content())
}
@inlinable
public var body: some TextNode {
style(.separator(.newLine(count: 1)))
}
}
public extension VStack {
/// Apply the given style to a ``VStack``.
///
/// - Parameters:
/// - style: The style to apply to the ``VStack``.
func style<S: VStackStyle>(_ style: S) -> some TextNode {
style.render(content: .init(content: content.removingEmptys()))
}
/// Apply the given separator to a ``VStack``.
///
/// - Parameters:
/// - separator: The vertical separator to use with the ``VStack``.
func separator(_ separator: Separator.Vertical) -> some TextNode {
style(.separator(separator))
}
}
// MARK: - Style
/// Style a ``VStack`` by creating a type that conforms to ``VStackStyle`` and use the
/// style by calling the ``VStack/style(_:)`` method on your instance.
///
public protocol VStackStyle: TextModifier where Content == StackConfiguration {}
public extension VStackStyle where Self == VStackSeparatorStyle {
/// Apply the given separator on a ``VStack``.
///
/// - See Also: ``VStack/separator(_:)``
///
/// - Parameters:
/// - separator: The vertical separator to use with the ``VStack``.
static func separator(_ separator: Separator.Vertical) -> Self {
VStackSeparatorStyle(separator: separator)
}
}
/// Separate items in a ``VStack`` with a given vertical separator.
///
/// - See Also: ``VStack/separator(_:)``.
///
public struct VStackSeparatorStyle: VStackStyle {
@usableFromInline
let separator: Separator.Vertical
@usableFromInline
init(separator: Separator.Vertical) {
self.separator = separator
}
@inlinable
public func render(content: StackConfiguration) -> some TextNode {
AnySeparatableStackNode(content: content, separator: separator)
}
}