aboutsummaryrefslogtreecommitdiff
path: root/Sources/NorgUI/Views/TreeNodesView.swift
diff options
context:
space:
mode:
authorRuben Beltran del Rio <jj@r.bdr.sh>2026-06-15 14:35:36 +0200
committerRuben Beltran del Rio <jj@r.bdr.sh>2026-06-16 14:47:30 +0200
commit657aa83a5ca24dc35572c040df64a0abb85e8612 (patch)
treefe0b6fd425d8cad9dc6a28ada4ad8600e42b367e /Sources/NorgUI/Views/TreeNodesView.swift
Initial extraction from Norganize
Diffstat (limited to 'Sources/NorgUI/Views/TreeNodesView.swift')
-rw-r--r--Sources/NorgUI/Views/TreeNodesView.swift48
1 files changed, 48 insertions, 0 deletions
diff --git a/Sources/NorgUI/Views/TreeNodesView.swift b/Sources/NorgUI/Views/TreeNodesView.swift
new file mode 100644
index 0000000..a509138
--- /dev/null
+++ b/Sources/NorgUI/Views/TreeNodesView.swift
@@ -0,0 +1,48 @@
+import NorgKit
+import SwiftUI
+
+struct TreeNodesView: View {
+ let nodes: [NorgNode]
+ let onSetStatus: (Int, TaskStatus) -> Void
+
+ var body: some View {
+ let siblingOrdinals = ordinals(forSiblings: nodes)
+ VStack(alignment: .leading, spacing: 10) {
+ ForEach(Array(nodes.enumerated()), id: \.offset) { index, node in
+ NodeView(node: node, ordinal: siblingOrdinals[index], onSetStatus: onSetStatus)
+ .id(node.block.line)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+ }
+ }
+}
+
+private struct NodeView: View {
+ let node: NorgNode
+ let ordinal: Int?
+ let onSetStatus: (Int, TaskStatus) -> Void
+
+ @State private var expanded = true
+
+ var body: some View {
+ if !node.children.isEmpty {
+ DisclosureGroup(isExpanded: $expanded) {
+ TreeNodesView(nodes: node.children, onSetStatus: onSetStatus)
+ } label: {
+ label
+ }
+ } else if let body = node.block.body, !body.isEmpty {
+ DisclosureGroup(isExpanded: $expanded) {
+ FlatBlocksView(blocks: body, onSetStatus: onSetStatus)
+ } label: {
+ label
+ }
+ } else {
+ label
+ }
+ }
+
+ private var label: some View {
+ BlockView(block: node.block, ordinal: ordinal, onSetStatus: onSetStatus)
+ }
+}