diff --git a/Apps/Examples/Examples/FioriSwiftUICore/SortFilter/SortFilterExample.swift b/Apps/Examples/Examples/FioriSwiftUICore/SortFilter/SortFilterExample.swift index 0141f2e1e..0ac2db5ef 100644 --- a/Apps/Examples/Examples/FioriSwiftUICore/SortFilter/SortFilterExample.swift +++ b/Apps/Examples/Examples/FioriSwiftUICore/SortFilter/SortFilterExample.swift @@ -6,6 +6,7 @@ struct SortFilterExample: View { [ .switch(item: .init(name: "Favorite", value: true, icon: "heart.fill"), showsOnFilterFeedbackBar: true), .switch(item: .init(name: "Tagged", value: nil, icon: "tag"), showsOnFilterFeedbackBar: false), + .picker(item: .init(name: "List No Search", value: [0], valueOptions: ["Received", "Started", "Hold"], allowsMultipleSelection: true, allowsEmptySelection: true, barItemDisplayMode: .name, isSearchBarHidden: true, icon: "clock", itemLayout: .fixed, displayMode: .list), showsOnFilterFeedbackBar: true), .picker(item: .init(name: "List Status", value: [0], valueOptions: ["Received", "Started", "Hold", "Transfer", "Completed", "Pending Review Pending Pending Pending Pending Pending", "Accepted Medium", "Pending Medium", "Completed Medium"], allowsMultipleSelection: true, allowsEmptySelection: true, barItemDisplayMode: .name, icon: "clock", itemLayout: .fixed, displayMode: .list), showsOnFilterFeedbackBar: true), .picker(item: .init(name: "List Many Status", value: [0], valueOptions: ["Received", "Started", "Hold", "Transfer", "Completed", "Pending Review Pending Pending Pending Pending Pending", "Accepted Medium", "Pending Medium", "Completed Medium", "Checked", "Unchecked", "Partially Checked", "Checked and Unchecked", "Checked and Partially Checked", "Unchecked and Partially Checked", "Partially Checked and Unchecked", "Checked and Unchecked and Partially Checked", "Unchecked and Partially Checked and Partially Checked", "Partially Checked and Unchecked and Partially Checked", "Checked Finally", "Unchecked Finally", "Partially Checked Finally", "Checked and Unchecked Finally", "Checked and Partially Checked Finally", "Unchecked and Partially Checked Finally", "Partially Checked and Unchecked Finally", "Checked Finally and Partially Checked Finally", "Unchecked Finally and Partially Checked Finally", "Partially Checked Finally and Partially Checked Finally", "Review", "Reviewed", "To be Reviewed", "Pending for Review", "Booked", "To be Booked", "Will Book", "Booking Canceled"], allowsMultipleSelection: true, allowsEmptySelection: true, barItemDisplayMode: .value, icon: "clock", itemLayout: .fixed, displayMode: .list), showsOnFilterFeedbackBar: true), .picker(item: .init(name: "Flexible Filter", value: [0], valueOptions: ["Received", "Started", "Hold", "Transfer", "Completed", "Pending Review Pending Pending Pending Pending Pending", "Accepted Medium", "Pending", "Completed Medium"], allowsMultipleSelection: true, allowsEmptySelection: true, barItemDisplayMode: .nameAndValue, icon: "clock", itemLayout: .flexible, displayMode: .filterFormCell), showsOnFilterFeedbackBar: true), @@ -16,6 +17,7 @@ struct SortFilterExample: View { .picker(item: .init(name: "Priority", value: [0], valueOptions: ["High", "Medium", "Low"], allowsMultipleSelection: true, allowsEmptySelection: true, showsValueForSingleSelected: false, icon: "filemenu.and.cursorarrow"), showsOnFilterFeedbackBar: true), .filterfeedback(item: .init(name: "Sort Order", value: [0], valueOptions: ["Ascending", "Descending"], allowsMultipleSelection: false, allowsEmptySelection: false, icon: "checkmark")), .stepper(item: .init(name: "Quantity", stepperTitle: "Label", value: 1, step: 1, stepRange: 0 ... 100, isDecimalSupported: false, description: "Hint Text"), showsOnFilterFeedbackBar: true) + ], [ .slider(item: .init(name: "User Stories", value: 10, minimumValue: 0, maximumValue: 100, formatter: "%2d Stories", icon: "number"), showsOnFilterFeedbackBar: true), diff --git a/Sources/FioriSwiftUICore/DataTypes/SortFilter+DataType.swift b/Sources/FioriSwiftUICore/DataTypes/SortFilter+DataType.swift index 68ade4dc7..b048151c1 100644 --- a/Sources/FioriSwiftUICore/DataTypes/SortFilter+DataType.swift +++ b/Sources/FioriSwiftUICore/DataTypes/SortFilter+DataType.swift @@ -363,6 +363,8 @@ public extension SortFilterItem { /// itemLayout is used when listPickerMode is filterFormCell, otherwise is ignored. public var itemLayout: OptionListPickerItemLayoutType = .fixed public var displayMode: DisplayMode = .automatic + /// If seachBar in list display mode is shown. Default is `false`. + public var isSearchBarHidden: Bool = false /// Available OptionListPicker modes. Use this enum to define picker mode to present. public enum DisplayMode { @@ -388,7 +390,7 @@ public extension SortFilterItem { case nameAndValue } - public init(id: String = UUID().uuidString, name: String, value: [Int], valueOptions: [String], allowsMultipleSelection: Bool, allowsEmptySelection: Bool, barItemDisplayMode: BarItemDisplayMode = .name, icon: String? = nil, itemLayout: OptionListPickerItemLayoutType = .fixed, displayMode: DisplayMode = .automatic) { + public init(id: String = UUID().uuidString, name: String, value: [Int], valueOptions: [String], allowsMultipleSelection: Bool, allowsEmptySelection: Bool, barItemDisplayMode: BarItemDisplayMode = .name, isSearchBarHidden: Bool = false, icon: String? = nil, itemLayout: OptionListPickerItemLayoutType = .fixed, displayMode: DisplayMode = .automatic) { self.id = id self.name = name self.value = value @@ -397,6 +399,7 @@ public extension SortFilterItem { self.valueOptions = valueOptions self.allowsMultipleSelection = allowsMultipleSelection self.allowsEmptySelection = allowsEmptySelection + self.isSearchBarHidden = isSearchBarHidden self.barItemDisplayMode = barItemDisplayMode self.icon = icon self.itemLayout = itemLayout diff --git a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift index c0742fa09..c5295e088 100644 --- a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift +++ b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift @@ -531,6 +531,7 @@ public protocol OptionListPickerItemModel: OptionListPickerComponent { // sourcery: virtualPropUpdateSearchListPickerHeight = "var updateSearchListPickerHeight: ((CGFloat) -> ())? = nil" // sourcery: virtualPropAllowsMultipleSelection = "var allowsMultipleSelection: Bool = false" // sourcery: virtualPropAllowsEmptySelection = "var allowsEmptySelection: Bool = false" +// sourcery: virtualPropIsSearchBarHidden = "var isSearchBarHidden: Bool = false" public protocol SearchListPickerItemModel: OptionListPickerComponent { // sourcery: default.value = nil // sourcery: no_view diff --git a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift index c92e7afe0..1c8a5b5ab 100644 --- a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift @@ -12,11 +12,12 @@ public extension SearchListPickerItem { /// - onTap: The closure when tap on item. /// - selectAll: The closure when click 'Select All' button. /// - updateSearchListPickerHeight: The closure to update the parent view. - init(value: Binding<[Int]>, valueOptions: [String] = [], hint: String? = nil, allowsMultipleSelection: Bool, allowsEmptySelection: Bool, onTap: ((_ index: Int) -> Void)? = nil, selectAll: ((_ isAll: Bool) -> Void)? = nil, updateSearchListPickerHeight: ((CGFloat) -> Void)? = nil) { + init(value: Binding<[Int]>, valueOptions: [String] = [], hint: String? = nil, allowsMultipleSelection: Bool, allowsEmptySelection: Bool, isSearchBarHidden: Bool = false, onTap: ((_ index: Int) -> Void)? = nil, selectAll: ((_ isAll: Bool) -> Void)? = nil, updateSearchListPickerHeight: ((CGFloat) -> Void)? = nil) { self.init(value: value, valueOptions: valueOptions, hint: hint, onTap: onTap) self.allowsMultipleSelection = allowsMultipleSelection self.allowsEmptySelection = allowsEmptySelection + self.isSearchBarHidden = isSearchBarHidden self.selectAll = selectAll self.updateSearchListPickerHeight = updateSearchListPickerHeight } @@ -71,7 +72,7 @@ extension SearchListPickerItem: View { let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 8 : 16) * 2 let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 13 : 16) * 2 let safeAreaInset = self.getSafeAreaInsets() - let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - 52 - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 230 : 30) + let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - (self.isSearchBarHidden ? 0 : 52) - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 230 : 30) self._height = min(scrollView.contentSize.height, maxScrollViewHeight) var isSelectAllViewShow = false if allowsMultipleSelection { @@ -88,7 +89,9 @@ extension SearchListPickerItem: View { .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393 : nil) .scrollContentBackground(.hidden) .padding(0) - .searchable(text: $_searchText, placement: .automatic) + .ifApply(!isSearchBarHidden, content: { v in + v.searchable(text: $_searchText, placement: .automatic) + }) } } diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift index f373597c7..59198529a 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift @@ -247,7 +247,7 @@ struct PickerMenuItem: View { }) .buttonStyle(ApplyButtonStyle()) } components: { - SearchListPickerItem(value: self.$item.workingValue, valueOptions: self.item.valueOptions, hint: nil, allowsMultipleSelection: self.item.allowsMultipleSelection, allowsEmptySelection: self.item.allowsEmptySelection) { index in + SearchListPickerItem(value: self.$item.workingValue, valueOptions: self.item.valueOptions, hint: nil, allowsMultipleSelection: self.item.allowsMultipleSelection, allowsEmptySelection: self.item.allowsEmptySelection, isSearchBarHidden: self.item.isSearchBarHidden) { index in self.item.onTap(option: self.item.valueOptions[index]) } selectAll: { isAll in self.item.selectAll(isAll) @@ -259,8 +259,8 @@ struct PickerMenuItem: View { Spacer() } .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393 : nil) - .frame(height: UIDevice.current.userInterfaceIdiom != .phone ? self.detentHeight + 52 + 56 + 70 : nil) - .presentationDetents([.large]) + .frame(height: UIDevice.current.userInterfaceIdiom != .phone ? self.detentHeight + (self.item.isSearchBarHidden ? 0 : 52) + 56 + 93 : nil) + .presentationDetents([.height(self.detentHeight + (self.item.isSearchBarHidden ? 0 : 52) + 56 + 93), .medium, .large]) } } } diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift index eddb1c528..c8251ddcb 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift @@ -118,7 +118,8 @@ extension _SortFilterCFGItemContainer: View { value: Binding<[Int]>(get: { self._items[r][c].picker.workingValue }, set: { self._items[r][c].picker.workingValue = $0 }), valueOptions: self._items[r][c].picker.valueOptions, allowsMultipleSelection: self._items[r][c].picker.allowsMultipleSelection, - allowsEmptySelection: self._items[r][c].picker.allowsEmptySelection + allowsEmptySelection: self._items[r][c].picker.allowsEmptySelection, + isSearchBarHidden: self._items[r][c].picker.isSearchBarHidden ) { index in self._items[r][c].picker.onTap(option: self._items[r][c].picker.valueOptions[index]) } selectAll: { isAll in diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift index e0aa1387e..525661a56 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift @@ -9,13 +9,14 @@ public struct SearchListPickerItem { var _valueOptions: [String] var _hint: String? = nil var _onTap: ((_ index: Int) -> Void)? = nil - @State var _searchText: String = "" - var allowsEmptySelection: Bool = false + var updateSearchListPickerHeight: ((CGFloat) -> ())? = nil + var allowsMultipleSelection: Bool = false + var isSearchBarHidden: Bool = false var selectAll: ((Bool) -> ())? = nil @State var _height: CGFloat = 44 - var allowsMultipleSelection: Bool = false - var updateSearchListPickerHeight: ((CGFloat) -> ())? = nil @State var _searchViewCornerRadius: CGFloat = 18 + @State var _searchText: String = "" + var allowsEmptySelection: Bool = false public init(model: SearchListPickerItemModel) { self.init(value: Binding<[Int]>(get: { model.value }, set: { model.value = $0 }), valueOptions: model.valueOptions, hint: model.hint, onTap: model.onTap) }