Skip to content

Commit

Permalink
fix: 🐛 [JIRA: IOSSDKBUG-157] isActive needed for ListPickerItem
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoyu0722 committed May 15, 2024
1 parent 4f627fb commit 1567b0f
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 16 deletions.
47 changes: 47 additions & 0 deletions Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct ListPickerItemExample: View {
case identifiable
case objectItem
case stringItem
case activeChildren
case searchable
case searchableListView
var id: Self { self }
Expand Down Expand Up @@ -85,6 +86,12 @@ struct ListPickerItemExample: View {
{
Text("StringItem")
}
case .activeChildren:
NavigationLink(
destination: ListPickerItemActiveChildrenExample())
{
Text("Active Children Directly")
}
case .searchable:
NavigationLink(
destination: ListPickerItemWithSearchExample())
Expand Down Expand Up @@ -299,8 +306,48 @@ public struct ListPickerItemWithStringExample: View {
}
}

struct ListPickerItemActiveChildrenExample: View {
private let model = ListPickerItemDataModel.data

@State var selections: Set<String> = []
@State var isActive: Bool = true

public init() {}

public var body: some View {
List {
ListPickerItem(key: {
Text("Frameworks")
}, value: {
let str = Array(selections).joined(separator: ", ")
Text(str)
}, configuration:
ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, isActive: self.$isActive, rowContent: { framework in
Text(framework.name)
}))
}
.listPickerListViewModifier { c in
c.navigationBarTitle(Text("Children"))
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
self.isActive.toggle()
} label: {
Image(systemName: "switch.2")
}
}
}
.navigationBarTitle(Text("Parent"))
}
}

struct ListPickerItemPreview: PreviewProvider {
static var previews: some View {
NavigationStack {
ListPickerItemActiveChildrenExample()
}

NavigationView {
ListPickerItemDataNonIdentifiableExample()
}
Expand Down
62 changes: 46 additions & 16 deletions Sources/FioriSwiftUICore/Views/ListPickerItem+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ extension Fiori {

extension ListPickerItem: View {
public var body: some View {
NavigationLink(
destination: self.destinationView,
label: {
KeyValueItem {
key
} value: {
value
if let isActive = destinationConfiguration?.isActive, isActive.wrappedValue {
self.destinationView
} else {
NavigationLink(
destination: self.destinationView,
label: {
KeyValueItem {
key
} value: {
value
}
}
}
)
)
}
}

@ViewBuilder
Expand Down Expand Up @@ -73,6 +77,9 @@ public extension ListPickerItem {
public struct ListPickerItemConfiguration {
let destinationView: AnyView

// A boolean that indicates whether show the children directly.
var isActive: Binding<Bool>?

/// Creates a searchable configuration object from a collection of data which supports single-level picker with the ability to select.
/// - Parameters:
/// - data: The data for constructing the list picker.
Expand Down Expand Up @@ -118,16 +125,18 @@ public struct ListPickerItemConfiguration {
/// - id: The key path to the data model's unique identifier.
/// - children: The key path to the optional property of a data element whose value indicates the children of that element.
/// - selection: A binding to a set which stores the selected items.
/// - isActive: A binding to a bool that decide if show children directly, Default value is nil.
/// - rowContent: The view builder which returns the content of each row in the list picker.
public init<Data, ID, RowContent>(_ data: Data,
id: KeyPath<Data.Element, ID>,
children: KeyPath<Data.Element, Data?>?,
selection: Binding<Set<ID>>?,
isActive: Binding<Bool>? = nil,
@ViewBuilder rowContent: @escaping (Data.Element) -> RowContent)
where Data: RandomAccessCollection, RowContent: View, ID: Hashable
{
self.destinationView = List {
ForEach(data, id: id) { element in
if let isActive, isActive.wrappedValue {
self.destinationView = ForEach(data, id: id) { element in
let row = rowContent(element)
let id_value = element[keyPath: id]

Expand All @@ -140,24 +149,44 @@ public struct ListPickerItemConfiguration {
} else {
ListPickerItem.Row(content: row, id: id_value, selection: selection)
}
}
}.typeErased
}.typeErased
} else {
self.destinationView = List {
ForEach(data, id: id) { element in
let row = rowContent(element)
let id_value = element[keyPath: id]

if let children, let childrenData = element[keyPath: children] {
ListPickerItem<RowContent, EmptyView>(key: {
row
}, value: {
EmptyView()
}, configuration: ListPickerItemConfiguration(childrenData, id: id, children: children, selection: selection, rowContent: rowContent))
} else {
ListPickerItem.Row(content: row, id: id_value, selection: selection)
}
}
}.typeErased
}
self.isActive = isActive
}

/// Creates a configuration object from a collection of data (conforms to `Identifiable`) which supports both single-level and multi-level picker with the ability to select multiple items.
/// - Parameters:
/// - data: The data for constructing the list picker.
/// - children: The key path to the optional property of a data element whose value indicates the children of that element.
/// - selection: A binding to a set which stores the selected items.
/// - isActive: A binding to a bool that decide if show children directly, Default value is nil.
/// - rowContent: The view builder which returns the content of each row in the list picker.
public init<Data, ID>(_ data: Data,
children: KeyPath<Data.Element, Data?>?,
selection: Binding<Set<ID>>?,
isActive: Binding<Bool>? = nil,
@ViewBuilder rowContent: @escaping (Data.Element) -> some View)
where Data: RandomAccessCollection, Data.Element: Identifiable, ID == Data.Element.ID
{
let id = \Data.Element.id
self.init(data, id: id, children: children, selection: selection, rowContent: rowContent)
self.init(data, id: id, children: children, selection: selection, isActive: isActive, rowContent: rowContent)
}
}

Expand All @@ -166,8 +195,9 @@ public extension ListPickerItemConfiguration {
/// - Parameters:
/// - data: An array of strings for constructing the list.
/// - selection: A binding to a set which stores the selected items.
init(_ data: [String], selection: Binding<Set<String>>?) {
self.init(data, id: \.self, children: nil, selection: selection) { str in
/// - isActive: A binding to a bool that decide if show children directly, Default value is nil.
init(_ data: [String], selection: Binding<Set<String>>?, isActive: Binding<Bool>? = nil) {
self.init(data, id: \.self, children: nil, selection: selection, isActive: isActive) { str in
Text(str)
}
}
Expand Down

0 comments on commit 1567b0f

Please sign in to comment.