59 lines
1.5 KiB
Swift
59 lines
1.5 KiB
Swift
public enum LabelContentStyle: Sendable {
|
|
case inline
|
|
case `default`
|
|
case custom(any NodeRepresentable)
|
|
}
|
|
|
|
public extension NodeRepresentable {
|
|
@inlinable
|
|
func labeledContentStyle(_ style: LabelContentStyle) -> any NodeRepresentable {
|
|
modifier(LabeledContentStyleModifier(style: style))
|
|
}
|
|
}
|
|
|
|
@usableFromInline
|
|
struct LabeledContentStyleModifier: NodeModifier {
|
|
|
|
@usableFromInline
|
|
let style: LabelContentStyle
|
|
|
|
@usableFromInline
|
|
init(style: LabelContentStyle) {
|
|
self.style = style
|
|
}
|
|
|
|
@usableFromInline
|
|
func render(_ node: any NodeRepresentable) -> any NodeRepresentable {
|
|
if let many = node as? _ManyNode {
|
|
var nodes = many.nodes
|
|
print("nodes: \(nodes)")
|
|
for (idx, node) in nodes.enumerated() {
|
|
if let labeled = node as? LabeledContent {
|
|
let newNode = labeled.applyingContentStyle(style)
|
|
nodes[idx] = newNode
|
|
}
|
|
}
|
|
return _ManyNode(nodes, separator: many.separator)
|
|
} else if let labeled = node as? LabeledContent {
|
|
return labeled.applyingContentStyle(style)
|
|
}
|
|
print("no many or labeled nodes found in: \(node)")
|
|
return node
|
|
}
|
|
|
|
}
|
|
|
|
private extension LabeledContent {
|
|
|
|
func applyingContentStyle(_ style: LabelContentStyle) -> Self {
|
|
switch style {
|
|
case .inline:
|
|
return .init(separator: " ") { label } content: { content }
|
|
case .default:
|
|
return .init(separator: "\n") { label } content: { content }
|
|
case let .custom(custom):
|
|
return .init(separator: custom) { label } content: { content }
|
|
}
|
|
}
|
|
}
|