diff --git a/Example/RoadmapExample/RoadmapExample/ContentView.swift b/Example/RoadmapExample/RoadmapExample/ContentView.swift index b6eff96..f61ead4 100644 --- a/Example/RoadmapExample/RoadmapExample/ContentView.swift +++ b/Example/RoadmapExample/RoadmapExample/ContentView.swift @@ -16,7 +16,7 @@ struct ContentView: View { allowSearching: true, allowsFilterByStatus: true ) - + var body: some View { #if os(macOS) roadmapView diff --git a/Sources/Roadmap/Models/RoadmapFeature.swift b/Sources/Roadmap/Models/RoadmapFeature.swift index 7322056..b5e6597 100644 --- a/Sources/Roadmap/Models/RoadmapFeature.swift +++ b/Sources/Roadmap/Models/RoadmapFeature.swift @@ -7,10 +7,11 @@ import Foundation -public struct RoadmapFeature: Codable, Identifiable { +public struct RoadmapFeature: Codable, Identifiable, Equatable { public let id: String public let title: String? public var status: String? = nil + public var url: URL? = nil private var description : String? = nil private var localizedTitle: [LocalizedItem]? = nil private var localizedStatus: [LocalizedItem]? = nil @@ -52,7 +53,7 @@ public struct RoadmapFeature: Codable, Identifiable { } } -struct LocalizedItem: Codable { +struct LocalizedItem: Codable, Equatable { let language: String let value: String } diff --git a/Sources/Roadmap/RoadmapView.swift b/Sources/Roadmap/RoadmapView.swift index 950cf33..07f783b 100644 --- a/Sources/Roadmap/RoadmapView.swift +++ b/Sources/Roadmap/RoadmapView.swift @@ -12,6 +12,7 @@ public struct RoadmapView: View { let header: Header let footer: Footer @State private var selectedFilter: String + @Binding var selectedFeature: RoadmapFeature? private var filterHorizontalPadding: CGFloat { #if os(macOS) @@ -64,6 +65,9 @@ public struct RoadmapView: View { RoadmapFeatureView(viewModel: viewModel.featureViewModel(for: feature)) .macOSListRowSeparatorHidden() .listRowBackground(Color.clear) + .onTapGesture { + selectedFeature = feature + } } footer } @@ -72,26 +76,26 @@ public struct RoadmapView: View { } public extension RoadmapView where Header == EmptyView, Footer == EmptyView { - init(configuration: RoadmapConfiguration) { - self.init(viewModel: .init(configuration: configuration), header: EmptyView(), footer: EmptyView(), selectedFilter: "") + init(configuration: RoadmapConfiguration, selectedFeature: Binding = .constant(nil)) { + self.init(viewModel: .init(configuration: configuration), header: EmptyView(), footer: EmptyView(), selectedFilter: "", selectedFeature: selectedFeature) } } public extension RoadmapView where Header: View, Footer == EmptyView { - init(configuration: RoadmapConfiguration, @ViewBuilder header: () -> Header) { - self.init(viewModel: .init(configuration: configuration), header: header(), footer: EmptyView(), selectedFilter: "") + init(configuration: RoadmapConfiguration, @ViewBuilder header: () -> Header, selectedFeature: Binding = .constant(nil)) { + self.init(viewModel: .init(configuration: configuration), header: header(), footer: EmptyView(), selectedFilter: "", selectedFeature: selectedFeature) } } public extension RoadmapView where Header == EmptyView, Footer: View { - init(configuration: RoadmapConfiguration, @ViewBuilder footer: () -> Footer) { - self.init(viewModel: .init(configuration: configuration), header: EmptyView(), footer: footer(), selectedFilter: "") + init(configuration: RoadmapConfiguration, @ViewBuilder footer: () -> Footer, selectedFeature: Binding = .constant(nil)) { + self.init(viewModel: .init(configuration: configuration), header: EmptyView(), footer: footer(), selectedFilter: "", selectedFeature: selectedFeature) } } public extension RoadmapView where Header: View, Footer: View { - init(configuration: RoadmapConfiguration, @ViewBuilder header: () -> Header, @ViewBuilder footer: () -> Footer) { - self.init(viewModel: .init(configuration: configuration), header: header(), footer: footer(), selectedFilter: "") + init(configuration: RoadmapConfiguration, @ViewBuilder header: () -> Header, @ViewBuilder footer: () -> Footer, selectedFeature: Binding = .constant(nil)) { + self.init(viewModel: .init(configuration: configuration), header: header(), footer: footer(), selectedFilter: "", selectedFeature: selectedFeature) } }