A SwiftUI wrapper around NSOutlineView that supports lazy child loading.
NSOutlineView
(and NSTableView
) can do an an enormous amount. This SwiftUI view can do just a little, but offers lazy, async child loading which OutlineGroup
cannot (currently) do. Hopefully one day! But in the meantime, maybe this will come in handy.
@MainActor
@Observable
final class OutlineModel {
private(set) var outlineData: OutlineData<MyItem, String>
var expansion = Set<String>()
var selection = Set<String>()
init() {
self.outlineData = OutlineData(
root: ..., // fill this in with your node type
subValues: {
// an async context to load children
return $0.children()
},
id: \.id,
hasSubvalues: \.hasChildren
)
}
static func configureView(_ view: NSOutlineView) {
// customize the view here
}
}
public struct Navigator: View {
@State private var model = OutlineModel()
var body: some View {
OutlineView(
data: model.outlineData, // core outline tree data
expansion: $model.expansion, // control expansion state
selection: $model.selection, // .. and selection
configuration: OutlineModel.configureView // optionally customize the underlying NSOutlineView
) { value in
Text(value.name)
}
}
}
I would love to hear from you! Issues or pull requests work great. Both a Matrix space and Discord are available for live help, but I have a strong bias towards answering in the form of documentation. You can also find me on mastodon.
I prefer collaboration, and would love to find ways to work together if you have a similar project.
I prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace.
By participating in this project you agree to abide by the Contributor Code of Conduct.