From 02f3d4a01d626f0eb574bcfa952bfb24dc3af757 Mon Sep 17 00:00:00 2001 From: xiaoyu0722 Date: Mon, 23 Sep 2024 13:35:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20[JIRA:=20HCPSDKFIORIUIKI?= =?UTF-8?q?T-2764]=20list=20picker=20enhancement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Examples.xcodeproj/project.pbxproj | 12 +- .../FioriSwiftUICore/CoreContentView.swift | 6 + .../FormCells/ListPickerItemExample.swift | 185 +++++ ...tPicker.swift => _ListPickerExample.swift} | 86 +- .../Models/ModelDefinitions.swift | 8 +- ...{FioriVStack.swift => CompactVStack.swift} | 0 .../Utils/String+Extension.swift | 10 + .../Views/SearchableListContent.swift | 28 +- ...+View.swift => _ListPickerItem+View.swift} | 28 +- .../BaseComponentProtocols.swift | 60 ++ .../CompositeComponentProtocols.swift | 34 + .../AllEntriesSectionTitleStyle.fiori.swift | 20 + .../_FioriStyles/ApplyActionStyle.fiori.swift | 19 + .../CancelActionStyle.fiori.swift | 19 + .../DeselectAllActionStyle.fiori.swift | 20 + .../ListPickerContentStyle.fiori.swift | 20 + .../ListPickerDestinationStyle.fiori.swift | 738 ++++++++++++++++++ .../ListPickerItemStyle.fiori.swift | 53 ++ .../SelectAllActionStyle.fiori.swift | 20 + ...lectedEntriesSectionTitleStyle.fiori.swift | 20 + .../_FioriStyles/ValueStyle.fiori.swift | 19 + .../AllEntriesSectionTitle.generated.swift | 63 ++ ...llEntriesSectionTitleStyle.generated.swift | 28 + .../ApplyAction/ApplyAction.generated.swift | 63 ++ .../ApplyActionStyle.generated.swift | 28 + .../CancelAction/CancelAction.generated.swift | 63 ++ .../CancelActionStyle.generated.swift | 28 + .../DeselectAllAction.generated.swift | 63 ++ .../DeselectAllActionStyle.generated.swift | 28 + .../ListPickerContent.generated.swift | 57 ++ .../ListPickerContentStyle.generated.swift | 28 + .../ListPickerDestination.generated.swift | 97 +++ ...ListPickerDestinationStyle.generated.swift | 53 ++ .../ListPickerItem.generated.swift | 100 +++ .../ListPickerItemStyle.generated.swift | 41 + .../SelectAllAction.generated.swift | 63 ++ .../SelectAllActionStyle.generated.swift | 28 + ...electedEntriesSectionTitle.generated.swift | 63 ++ ...edEntriesSectionTitleStyle.generated.swift | 28 + .../Value/Value.generated.swift | 63 ++ .../Value/ValueStyle.generated.swift | 28 + ...entStyleProtocol+Extension.generated.swift | 329 ++++++++ .../EnvironmentVariables.generated.swift | 210 +++++ .../ModifiedStyle.generated.swift | 280 +++++++ .../ResolvedStyle.generated.swift | 160 ++++ .../View+Extension_.generated.swift | 170 ++++ ...iewEmptyChecking+Extension.generated.swift | 68 ++ ...ft => _ListPickerItem+API.generated.swift} | 19 +- ...t => _ListPickerItem+View.generated.swift} | 16 +- ...t => _ListPickerItem+Init.generated.swift} | 2 +- ...ickerItemModel+Extensions.generated.swift} | 2 +- .../en.lproj/FioriSwiftUICore.strings | 9 + .../.lib/Sources/utils/Type+Extensions.swift | 7 +- 53 files changed, 3593 insertions(+), 97 deletions(-) create mode 100644 Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPickerItemExample.swift rename Apps/Examples/Examples/FioriSwiftUICore/FormCells/{ListPicker.swift => _ListPickerExample.swift} (77%) rename Sources/FioriSwiftUICore/Utils/{FioriVStack.swift => CompactVStack.swift} (100%) create mode 100644 Sources/FioriSwiftUICore/Utils/String+Extension.swift rename Sources/FioriSwiftUICore/Views/{ListPickerItem+View.swift => _ListPickerItem+View.swift} (93%) create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/AllEntriesSectionTitleStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/ApplyActionStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/CancelActionStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/DeselectAllActionStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/ListPickerContentStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/ListPickerDestinationStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/ListPickerItemStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/SelectAllActionStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/SelectedEntriesSectionTitleStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_FioriStyles/ValueStyle.fiori.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitleStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyAction.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyActionStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelAction.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelActionStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllAction.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllActionStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContent.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContentStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestination.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestinationStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItem.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItemStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllAction.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllActionStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitleStyle.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/Value.generated.swift create mode 100644 Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/ValueStyle.generated.swift rename Sources/FioriSwiftUICore/_generated/ViewModels/API/{ListPickerItem+API.generated.swift => _ListPickerItem+API.generated.swift} (68%) rename Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/{ListPickerItem+View.generated.swift => _ListPickerItem+View.generated.swift} (80%) rename Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/{ListPickerItem+Init.generated.swift => _ListPickerItem+Init.generated.swift} (84%) rename Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/{ListPickerItemModel+Extensions.generated.swift => _ListPickerItemModel+Extensions.generated.swift} (81%) diff --git a/Apps/Examples/Examples.xcodeproj/project.pbxproj b/Apps/Examples/Examples.xcodeproj/project.pbxproj index bfa321383..cf709e398 100644 --- a/Apps/Examples/Examples.xcodeproj/project.pbxproj +++ b/Apps/Examples/Examples.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 108E43D5292DAB7C006532F3 /* EmptyStateViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108E43D4292DAB7C006532F3 /* EmptyStateViewExample.swift */; }; 1F1A1FFA2C0BDA54007109D8 /* MenuSelectionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1A1FF92C0BDA54007109D8 /* MenuSelectionExample.swift */; }; 1F26DCFA261A5CD9006C43B1 /* FioriButtonContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F26DCF9261A5CD9006C43B1 /* FioriButtonContentView.swift */; }; - 1F3C92F125DF12C100A99A07 /* ListPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F3C92F025DF12C100A99A07 /* ListPicker.swift */; }; + 1F3C92F125DF12C100A99A07 /* _ListPickerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F3C92F025DF12C100A99A07 /* _ListPickerExample.swift */; }; 1F55FEF32AC941FF00D7A1BE /* View+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F55FEF22AC941FF00D7A1BE /* View+Extensions.swift */; }; 1F60179729A8439A00DBDCDE /* WatchExamplesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F60179629A8439A00DBDCDE /* WatchExamplesApp.swift */; }; 1F60179929A8439A00DBDCDE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F60179829A8439A00DBDCDE /* ContentView.swift */; }; @@ -114,6 +114,7 @@ B100639329C0624D00AF0CA2 /* StepProgressIndicatorExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100639229C0624D00AF0CA2 /* StepProgressIndicatorExample.swift */; }; B13408922B01FA0700600331 /* NavigationBarExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B13408912B01FA0700600331 /* NavigationBarExample.swift */; }; B141D6BB29261F9E008A8BD6 /* SearchableListViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */; }; + B153E88E2CAA8EEA0017EB84 /* ListPickerItemExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B153E88D2CAA8EE30017EB84 /* ListPickerItemExample.swift */; }; B18D2E9F2988B07B000A1821 /* KPIHeaderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B18D2E9E2988B07B000A1821 /* KPIHeaderExample.swift */; }; B18D593C2B0C52C700ABB1AD /* TabViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B18D593B2B0C52C700ABB1AD /* TabViewExample.swift */; }; B190065A2C201BBE000C8B10 /* ProfileHeaderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19006592C201BBE000C8B10 /* ProfileHeaderExample.swift */; }; @@ -224,7 +225,7 @@ 108E43D4292DAB7C006532F3 /* EmptyStateViewExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStateViewExample.swift; sourceTree = ""; }; 1F1A1FF92C0BDA54007109D8 /* MenuSelectionExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuSelectionExample.swift; sourceTree = ""; }; 1F26DCF9261A5CD9006C43B1 /* FioriButtonContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FioriButtonContentView.swift; sourceTree = ""; }; - 1F3C92F025DF12C100A99A07 /* ListPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListPicker.swift; sourceTree = ""; }; + 1F3C92F025DF12C100A99A07 /* _ListPickerExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _ListPickerExample.swift; sourceTree = ""; }; 1F55FEF22AC941FF00D7A1BE /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = ""; }; 1F60179429A8439A00DBDCDE /* WatchExamples Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WatchExamples Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 1F60179629A8439A00DBDCDE /* WatchExamplesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchExamplesApp.swift; sourceTree = ""; }; @@ -326,6 +327,7 @@ B100639229C0624D00AF0CA2 /* StepProgressIndicatorExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepProgressIndicatorExample.swift; sourceTree = ""; }; B13408912B01FA0700600331 /* NavigationBarExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarExample.swift; sourceTree = ""; }; B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchableListViewExample.swift; sourceTree = ""; }; + B153E88D2CAA8EE30017EB84 /* ListPickerItemExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListPickerItemExample.swift; sourceTree = ""; }; B18D2E9E2988B07B000A1821 /* KPIHeaderExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KPIHeaderExample.swift; sourceTree = ""; }; B18D593B2B0C52C700ABB1AD /* TabViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabViewExample.swift; sourceTree = ""; }; B19006592C201BBE000C8B10 /* ProfileHeaderExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderExample.swift; sourceTree = ""; }; @@ -425,8 +427,9 @@ 1F3C92EF25DF12A100A99A07 /* FormCells */ = { isa = PBXGroup; children = ( + B153E88D2CAA8EE30017EB84 /* ListPickerItemExample.swift */, 878219C32BEE128E002FDFBC /* StepperViewExample.swift */, - 1F3C92F025DF12C100A99A07 /* ListPicker.swift */, + 1F3C92F025DF12C100A99A07 /* _ListPickerExample.swift */, B141D6BA29261F9E008A8BD6 /* SearchableListViewExample.swift */, 99193C842B719B8800F33BAF /* InformationViewExample.swift */, 64905D062C6D13E20062AAD4 /* SwitchExample.swift */, @@ -1063,7 +1066,7 @@ 99B6EF8C2672224D00515E8E /* UserConsentSample.swift in Sources */, B84D24F02652F343007F2373 /* ObjectHeaderExample.swift in Sources */, 9996CD00262EB4E8001B99AE /* EULAViewSample.swift in Sources */, - 1F3C92F125DF12C100A99A07 /* ListPicker.swift in Sources */, + 1F3C92F125DF12C100A99A07 /* _ListPickerExample.swift in Sources */, B1D41B20291A2D97004E64A5 /* DurationPickerExample.swift in Sources */, 1FC30414270541BF004BEE00 /* FioriThemeManagerContentView.swift in Sources */, C106AD422B336EA400FE8B35 /* SearchWithSuggestion.swift in Sources */, @@ -1123,6 +1126,7 @@ 6D6E86712C53A0D500EDB6F4 /* CardViewWithTwoButtonsExample.swift in Sources */, B8D4376F25F980340024EE7D /* ObjectCell_Spec_Jan2018.swift in Sources */, 8A5579CF24C1293C0098003A /* SettingsAxis.swift in Sources */, + B153E88E2CAA8EEA0017EB84 /* ListPickerItemExample.swift in Sources */, B80DA9BC260BED9400C0B2E9 /* SingleActionCollectionView.swift in Sources */, 8732C2CB2C3524D9002110E9 /* CustomTimelineExample.swift in Sources */, 8A5579D924C1293C0098003A /* SettingsSelection.swift in Sources */, diff --git a/Apps/Examples/Examples/FioriSwiftUICore/CoreContentView.swift b/Apps/Examples/Examples/FioriSwiftUICore/CoreContentView.swift index 3e68cf6c6..72b472629 100644 --- a/Apps/Examples/Examples/FioriSwiftUICore/CoreContentView.swift +++ b/Apps/Examples/Examples/FioriSwiftUICore/CoreContentView.swift @@ -190,6 +190,12 @@ struct CoreContentView: View { } Section(header: Text("Pickers")) { + NavigationLink( + destination: _ListPickerItemExample()) + { + Text("_ListPickerItem") + } + NavigationLink( destination: ListPickerItemExample()) { diff --git a/Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPickerItemExample.swift b/Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPickerItemExample.swift new file mode 100644 index 000000000..1947a57ed --- /dev/null +++ b/Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPickerItemExample.swift @@ -0,0 +1,185 @@ +import FioriSwiftUICore +import SwiftUI + +struct ListPickerItemExample: View { + private let model = ListPickerItemDataModel.data + private let stringsModel = ["First", "Second", "Third", "Fourth", "Fifth"] + + @State var selections: Set = [] + @State var selection: String? = nil + + @State var noneEmptySelection: String = "UIKit" + + @State var axis: Axis = .horizontal + @State var useSimpleModel: Bool = false + + @State var multiSelections: Bool = false + @State var isTrackingLiveChanges: Bool = false + @State var allowSearch: Bool = false + @State var customDestination: Bool = false + @State var disableEntriesSection: Bool = false + @State var allowEmpty: Bool = false + + var body: some View { + List { + ListPickerItem(title: { + Text("Frameworks") + }, value: { + self.valueView + }, axis: self.axis, + destination: { + self.destinationView + .disableEntriesSection(self.disableEntriesSection) + .navigationTitle("Destination Title") + .ifApply(self.customDestination) { + $0.cancelActionStyle { _ in + Button { + print("This is dismiss without selections") + } label: { + Image(systemName: "chevron.left") + } + } + .applyActionStyle { _ in + Button { + print("This is dismiss with selections") + } label: { + Image(systemName: "checkmark") + } + } + .allEntriesSectionTitleStyle { _ in + Text("All Entries Title") + } + .selectedEntriesSectionTitleStyle { _ in + Text("Selected Entries Title") + } + .selectAllActionStyle { _ in + FioriButton(title: "Select All Action") { _ in } + } + .deselectAllActionStyle { _ in + FioriButton(title: "Deselect All Action") { _ in } + } + .listStyle(.plain) + } + }) + .onChange(of: self.useSimpleModel) { _ in + self.selections.removeAll() + self.selection = nil + self.noneEmptySelection = self.useSimpleModel ? "First" : "UIKit" + } + + Section("Pannel") { + Picker("Axis", selection: self.$axis) { + Text("Horizontal").tag(Axis.horizontal) + Text("Vertical").tag(Axis.vertical) + } + + Toggle("Use simple model", isOn: self.$useSimpleModel) + + Toggle("Multi Selections", isOn: self.$multiSelections) + + Toggle("Tracking Live Changes", isOn: self.$isTrackingLiveChanges) + + Toggle("Search Support", isOn: self.$allowSearch) + + Toggle("Custom Destination", isOn: self.$customDestination) + + Toggle("Disable Entries Section", isOn: self.$disableEntriesSection) + + Toggle("Allow Empty", isOn: self.$allowEmpty) + } + } + } + + @ViewBuilder var valueView: some View { + if self.multiSelections { + let str = Array(selections).joined(separator: ", ") + Text(str) + } else { + if self.allowEmpty { + Text(self.selection ?? "No Selection") + } else { + Text(self.noneEmptySelection) + } + } + } + + @ViewBuilder var destinationView: some View { + if self.useSimpleModel { + let filter: (String, String) -> Bool = { f, s in f.contains(s) } + if self.multiSelections { + ListPickerDestination(self.stringsModel, + id: \.self, + selections: self.$selections, + allowEmpty: self.allowEmpty, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? { f, s in f.contains(s) } : nil) + { e in + Text(e) + } + } else { + if self.allowEmpty { + ListPickerDestination(self.stringsModel, + id: \.self, + selection: self.$selection, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? filter : nil) + { e in + Text(e) + } + } else { + ListPickerDestination(self.stringsModel, + id: \.self, + selection: self.$noneEmptySelection, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? filter : nil) + { e in + Text(e) + } + } + } + } else { + let filter: ((ListPickerItemDataModel.Framework, String) -> Bool) = { f, s in + if s.count > 0 { + return f.name.localizedCaseInsensitiveContains(s) + } else { + return true + } + } + + if self.multiSelections { + ListPickerDestination(self.model, + id: \.name, + children: \.children, + selections: self.$selections, + allowEmpty: self.allowEmpty, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? filter : nil) + { e in + Text(e.name) + } + } else { + if self.allowEmpty { + ListPickerDestination(self.model, + id: \.name, + children: \.children, + selection: self.$selection, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? filter : nil) + { e in + Text(e.name) + } + } else { + ListPickerDestination(self.model, + id: \.name, + children: \.children, + selection: self.$noneEmptySelection, + isTrackingLiveChanges: self.isTrackingLiveChanges, + searchFilter: self.allowSearch ? filter : nil) + { e in + Text(e.name) + } + } + } + } + } +} diff --git a/Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPicker.swift b/Apps/Examples/Examples/FioriSwiftUICore/FormCells/_ListPickerExample.swift similarity index 77% rename from Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPicker.swift rename to Apps/Examples/Examples/FioriSwiftUICore/FormCells/_ListPickerExample.swift index b815ef390..6c8c9b9bc 100644 --- a/Apps/Examples/Examples/FioriSwiftUICore/FormCells/ListPicker.swift +++ b/Apps/Examples/Examples/FioriSwiftUICore/FormCells/_ListPickerExample.swift @@ -45,7 +45,7 @@ enum ListPickerItemDataModel { } } -struct ListPickerItemExample: View { +struct _ListPickerItemExample: View { enum ListPickerCases: CaseIterable, Identifiable { case nonIdentifiable case identifiable @@ -61,47 +61,47 @@ struct ListPickerItemExample: View { private let model = ListPickerItemDataModel.data var body: some View { - List(ListPickerItemExample.ListPickerCases.allCases) { e in + List(_ListPickerItemExample.ListPickerCases.allCases) { e in switch e { case .nonIdentifiable: NavigationLink( - destination: ListPickerItemDataNonIdentifiableExample()) + destination: _ListPickerItemDataNonIdentifiableExample()) { Text("NonIdentifiable") } case .identifiable: NavigationLink( - destination: ListPickerItemDataIdentifiableExample()) + destination: _ListPickerItemDataIdentifiableExample()) { Text("Identifiable") } case .objectItem: NavigationLink( - destination: ListPickerItemWithObjectItemExample()) + destination: _ListPickerItemWithObjectItemExample()) { Text("ObjectItem") } case .stringItem: NavigationLink( - destination: ListPickerItemWithStringExample()) + destination: _ListPickerItemWithStringExample()) { Text("StringItem") } case .differentStyles: NavigationLink( - destination: ListPickerItemStylesExample()) + destination: _ListPickerItemStylesExample()) { Text("Different Styles") } case .activeChildren: NavigationLink( - destination: ListPickerItemActiveChildrenExample()) + destination: _ListPickerItemActiveChildrenExample()) { Text("Active Children Directly") } case .searchable: NavigationLink( - destination: ListPickerItemWithSearchExample()) + destination: _ListPickerItemWithSearchExample()) { Text("Searchable List Picker Item") } @@ -122,7 +122,7 @@ struct ListPickerItemExample: View { // MARK: List picker item examples -struct ListPickerItemDataNonIdentifiableExample: View { +struct _ListPickerItemDataNonIdentifiableExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] @@ -131,13 +131,13 @@ struct ListPickerItemDataNonIdentifiableExample: View { public var body: some View { List { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).joined(separator: ", ") Text(str) }, configuration: - ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in + _ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in Text(framework.name) })) } @@ -156,7 +156,7 @@ struct ListPickerItemDataNonIdentifiableExample: View { } } -struct ListPickerItemDataIdentifiableExample: View { +struct _ListPickerItemDataIdentifiableExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] @@ -165,7 +165,7 @@ struct ListPickerItemDataIdentifiableExample: View { public var body: some View { List { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).compactMap { uuid in @@ -178,7 +178,7 @@ struct ListPickerItemDataIdentifiableExample: View { Text(str) }, configuration: - ListPickerItemConfiguration(self.model, children: \.children, selection: self.$selections, rowContent: { framework in + _ListPickerItemConfiguration(self.model, children: \.children, selection: self.$selections, rowContent: { framework in Text(framework.name) })) } @@ -186,19 +186,19 @@ struct ListPickerItemDataIdentifiableExample: View { } } -struct ListPickerItemFormExample: View { +struct _ListPickerItemFormExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] var body: some View { Form { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).joined(separator: ", ") Text(str) - }, configuration: ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in + }, configuration: _ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in Text(framework.name) })) } @@ -206,7 +206,7 @@ struct ListPickerItemFormExample: View { } } -struct ListPickerItemWithSearchExample: View { +struct _ListPickerItemWithSearchExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] @@ -215,7 +215,7 @@ struct ListPickerItemWithSearchExample: View { var body: some View { List { if #available(iOS 15.0, *) { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).compactMap { uuid in @@ -225,7 +225,7 @@ struct ListPickerItemWithSearchExample: View { return nil }.joined(separator: ", ") Text(str) - }, configuration: ListPickerItemConfiguration(model, id: \.id, children: \.children, selection: $selections, searchFilter: { framework, searchText in + }, configuration: _ListPickerItemConfiguration(model, id: \.id, children: \.children, selection: $selections, searchFilter: { framework, searchText in if searchText.count > 0 { return framework.name.localizedCaseInsensitiveContains(searchText) } else { @@ -243,7 +243,7 @@ struct ListPickerItemWithSearchExample: View { } })) } else { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).compactMap { uuid in @@ -254,7 +254,7 @@ struct ListPickerItemWithSearchExample: View { return nil }.joined(separator: ", ") Text(str) - }, configuration: ListPickerItemConfiguration(self.model, id: \.id, children: \.children, selection: self.$selections, rowContent: { framework in + }, configuration: _ListPickerItemConfiguration(self.model, id: \.id, children: \.children, selection: self.$selections, rowContent: { framework in Text(framework.name) })) } @@ -262,19 +262,19 @@ struct ListPickerItemWithSearchExample: View { } } -struct ListPickerItemWithObjectItemExample: View { +struct _ListPickerItemWithObjectItemExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] var body: some View { List { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Frameworks") }, value: { let str = Array(selections).joined(separator: ", ") Text(str) - }, configuration: ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in + }, configuration: _ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, rowContent: { framework in ObjectItem { Text(framework.name) @@ -292,7 +292,7 @@ struct ListPickerItemWithObjectItemExample: View { } } -public struct ListPickerItemWithStringExample: View { +public struct _ListPickerItemWithStringExample: View { private let model = ["First", "Second", "Third", "Fourth", "Fifth"] @State var selections: Set = [] @@ -301,19 +301,19 @@ public struct ListPickerItemWithStringExample: View { public var body: some View { List { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Choice") }, value: { let str = Array(selections).joined(separator: ", ") Text(str) }, configuration: - ListPickerItemConfiguration(self.model, selection: self.$selections)) + _ListPickerItemConfiguration(self.model, selection: self.$selections)) } .navigationBarTitle(Text("Form")) } } -struct ListPickerItemActiveChildrenExample: View { +struct _ListPickerItemActiveChildrenExample: View { private let model = ListPickerItemDataModel.data @State var selections: Set = [] @@ -323,13 +323,13 @@ struct ListPickerItemActiveChildrenExample: View { public var body: some View { List { - ListPickerItem(key: { + _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 + _ListPickerItemConfiguration(self.model, id: \.name, children: \.children, selection: self.$selections, isActive: self.$isActive, rowContent: { framework in Text(framework.name) })) } @@ -349,7 +349,7 @@ struct ListPickerItemActiveChildrenExample: View { } } -public struct ListPickerItemStylesExample: View { +public struct _ListPickerItemStylesExample: View { private let model = ["First", "Second", "Third", "Fourth", "Fifth"] @State var selections: Set = ["Second"] @@ -360,14 +360,14 @@ public struct ListPickerItemStylesExample: View { public var body: some View { List { Section("List Picker Item") { - ListPickerItem(key: { + _ListPickerItem(key: { Text("Choice") }, value: { let str = Array(selections).joined(separator: ", ") Text(str) }, axis: self.axis, configuration: - ListPickerItemConfiguration(self.model, selection: self.$selections)) + _ListPickerItemConfiguration(self.model, selection: self.$selections)) .disabled(!self.isEnabled) } @@ -383,34 +383,34 @@ public struct ListPickerItemStylesExample: View { } } -struct ListPickerItemPreview: PreviewProvider { +struct _ListPickerItemPreview: PreviewProvider { static var previews: some View { NavigationStack { - ListPickerItemActiveChildrenExample() + _ListPickerItemActiveChildrenExample() } NavigationView { - ListPickerItemDataNonIdentifiableExample() + _ListPickerItemDataNonIdentifiableExample() } NavigationView { - ListPickerItemDataIdentifiableExample() + _ListPickerItemDataIdentifiableExample() } NavigationView { - ListPickerItemFormExample() + _ListPickerItemFormExample() } NavigationView { - ListPickerItemWithObjectItemExample() + _ListPickerItemWithObjectItemExample() } NavigationView { - ListPickerItemWithStringExample() + _ListPickerItemWithStringExample() } NavigationView { - ListPickerItemWithSearchExample() + _ListPickerItemWithSearchExample() } } } diff --git a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift index ed60a9d48..8b074e5b0 100644 --- a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift +++ b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift @@ -106,13 +106,17 @@ public protocol ActivityItemsModel: ActionItemsComponent {} // sourcery: add_env_props = "listBackground" // sourcery: add_env_props = "listpickerListStyle" // sourcery: add_env_props = "listPickerListViewModifier" -// sourcery: virtualPropDestinationConfiguration = "var destinationConfiguration: ListPickerItemConfiguration? = nil" -public protocol ListPickerItemModel: KeyComponent, ValueComponent { + +// sourcery: virtualPropDestinationConfiguration = "var destinationConfiguration: _ListPickerItemConfiguration? = nil" +public protocol _ListPickerItemModel: KeyComponent, ValueComponent { // sourcery: default.value = .horizontal // sourcery: no_view var axis: Axis { get } } +@available(*, unavailable, renamed: "_ListPickerItemModel", message: "Will be removed in the future release. Please create ListPickerItem with other initializers instead.") +public protocol ListPickerItemModel {} + // sourcery: generated_component_not_configurable public protocol ProgressIndicatorModel: ProgressIndicatorComponent {} diff --git a/Sources/FioriSwiftUICore/Utils/FioriVStack.swift b/Sources/FioriSwiftUICore/Utils/CompactVStack.swift similarity index 100% rename from Sources/FioriSwiftUICore/Utils/FioriVStack.swift rename to Sources/FioriSwiftUICore/Utils/CompactVStack.swift diff --git a/Sources/FioriSwiftUICore/Utils/String+Extension.swift b/Sources/FioriSwiftUICore/Utils/String+Extension.swift new file mode 100644 index 000000000..39563d786 --- /dev/null +++ b/Sources/FioriSwiftUICore/Utils/String+Extension.swift @@ -0,0 +1,10 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +public extension String { + /// Localized string by `FioriSwiftUICore` + func localizedFioriString(_ comment: String = "") -> String { + NSLocalizedString(self, tableName: "FioriSwiftUICore", bundle: Bundle.accessor, comment: comment) + } +} diff --git a/Sources/FioriSwiftUICore/Views/SearchableListContent.swift b/Sources/FioriSwiftUICore/Views/SearchableListContent.swift index 9d574fb56..8aabf46c3 100644 --- a/Sources/FioriSwiftUICore/Views/SearchableListContent.swift +++ b/Sources/FioriSwiftUICore/Views/SearchableListContent.swift @@ -127,25 +127,25 @@ struct SearchableListContent(key: { + _ListPickerItem(key: { row }, value: { EmptyView() - }, configuration: ListPickerItemConfiguration(childrenData, - id: self.id, - children: children, - selection: !self.isTopLevel ? self.selection : self.$selectionBuffer, - isTopLevel: false, - allowsMultipleSelection: self.allowsMultipleSelection, - searchFilter: self.searchFilter, - rowContent: self.rowContent, - rowBackground: self.rowBackground)) + }, configuration: _ListPickerItemConfiguration(childrenData, + id: self.id, + children: children, + selection: !self.isTopLevel ? self.selection : self.$selectionBuffer, + isTopLevel: false, + allowsMultipleSelection: self.allowsMultipleSelection, + searchFilter: self.searchFilter, + rowContent: self.rowContent, + rowBackground: self.rowBackground)) .environment(\.listBackground, self.listBackground) } else { - ListPickerItem.Row(content: row, - id: id_value, - selection: !self.isTopLevel ? self.selection : self.$selectionBuffer, - allowsMultipleSelection: self.allowsMultipleSelection) + _ListPickerItem.Row(content: row, + id: id_value, + selection: !self.isTopLevel ? self.selection : self.$selectionBuffer, + allowsMultipleSelection: self.allowsMultipleSelection) } } .listRowBackground(Group { diff --git a/Sources/FioriSwiftUICore/Views/ListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/_ListPickerItem+View.swift similarity index 93% rename from Sources/FioriSwiftUICore/Views/ListPickerItem+View.swift rename to Sources/FioriSwiftUICore/Views/_ListPickerItem+View.swift index 61d52a5ce..59afe1671 100644 --- a/Sources/FioriSwiftUICore/Views/ListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/_ListPickerItem+View.swift @@ -5,7 +5,7 @@ import SwiftUI // FIXME: - Implement Fiori style definitions extension Fiori { - enum ListPickerItem { + enum _ListPickerItem { struct Key: ViewModifier { func body(content: Content) -> some View { content.font(.fiori(forTextStyle: .subheadline, weight: .bold)).foregroundColor(.preferredColor(.primaryLabel)) @@ -26,7 +26,7 @@ extension Fiori { // FIXME: - Implement ListPickerItem View body -extension ListPickerItem: View { +extension _ListPickerItem: View { public var body: some View { if let isActive = destinationConfiguration?.isActive, isActive.wrappedValue { self.destinationView @@ -57,7 +57,7 @@ extension ListPickerItem: View { } } -public extension ListPickerItem { +public extension _ListPickerItem { /// Returns a list picker item with given configuration. /// - Parameters: /// - key: The key view of the list. @@ -68,7 +68,7 @@ public extension ListPickerItem { @ViewBuilder key: @escaping () -> Key, @ViewBuilder value: @escaping () -> Value, axis: Axis = .horizontal, - configuration: ListPickerItemConfiguration? = nil + configuration: _ListPickerItemConfiguration? = nil ) { self.init(key: key, value: value, axis: axis) self.destinationConfiguration = configuration @@ -76,7 +76,7 @@ public extension ListPickerItem { } /// The configuration for constructing the list picker. -public struct ListPickerItemConfiguration { +public struct _ListPickerItemConfiguration { let destinationView: AnyView // A boolean that indicates whether show the children directly. @@ -143,13 +143,13 @@ public struct ListPickerItemConfiguration { let id_value = element[keyPath: id] if let children, let childrenData = element[keyPath: children] { - ListPickerItem(key: { + _ListPickerItem(key: { row }, value: { EmptyView() - }, configuration: ListPickerItemConfiguration(childrenData, id: id, children: children, selection: selection, rowContent: rowContent)) + }, configuration: _ListPickerItemConfiguration(childrenData, id: id, children: children, selection: selection, rowContent: rowContent)) } else { - ListPickerItem.Row(content: row, id: id_value, selection: selection) + _ListPickerItem.Row(content: row, id: id_value, selection: selection) } }.typeErased } else { @@ -159,13 +159,13 @@ public struct ListPickerItemConfiguration { let id_value = element[keyPath: id] if let children, let childrenData = element[keyPath: children] { - ListPickerItem(key: { + _ListPickerItem(key: { row }, value: { EmptyView() - }, configuration: ListPickerItemConfiguration(childrenData, id: id, children: children, selection: selection, rowContent: rowContent)) + }, configuration: _ListPickerItemConfiguration(childrenData, id: id, children: children, selection: selection, rowContent: rowContent)) } else { - ListPickerItem.Row(content: row, id: id_value, selection: selection) + _ListPickerItem.Row(content: row, id: id_value, selection: selection) } } }.typeErased @@ -192,7 +192,7 @@ public struct ListPickerItemConfiguration { } } -public extension ListPickerItemConfiguration { +public extension _ListPickerItemConfiguration { /// Creates a configuration object from a collection of `String` which supports both single-level and multi-level picker with the ability to select multiple items. /// - Parameters: /// - data: An array of strings for constructing the list. @@ -205,7 +205,7 @@ public extension ListPickerItemConfiguration { } } -extension ListPickerItemConfiguration { +extension _ListPickerItemConfiguration { @available(iOS 15.0, macOS 12.0, *) init( _ data: Data, @@ -233,7 +233,7 @@ extension ListPickerItemConfiguration { } } -extension ListPickerItem { +extension _ListPickerItem { struct Row: View where Value == EmptyView { private let content: Key private let id: ID diff --git a/Sources/FioriSwiftUICore/_ComponentProtocols/BaseComponentProtocols.swift b/Sources/FioriSwiftUICore/_ComponentProtocols/BaseComponentProtocols.swift index 37d475344..b58da51af 100755 --- a/Sources/FioriSwiftUICore/_ComponentProtocols/BaseComponentProtocols.swift +++ b/Sources/FioriSwiftUICore/_ComponentProtocols/BaseComponentProtocols.swift @@ -372,3 +372,63 @@ protocol _HalfStarImageComponent { // sourcery: defaultValue = "FioriIcon.actions.halfStar.renderingMode(.template).resizable()" var halfStarImage: Image { get } } + +// sourcery: BaseComponent +protocol _ValueComponent { + // sourcery: @ViewBuilder + var value: AttributedString? { get } +} + +// sourcery: BaseComponent +protocol _CancelActionComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "FioriButton { _ in Text("Cancel".localizedFioriString()) }" + // sourcery: resultBuilder.defaultValue = "{ FioriButton { _ in Text("Cancel".localizedFioriString()) } }" + var cancelAction: FioriButton? { get } +} + +// sourcery: BaseComponent +protocol _ApplyActionComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "FioriButton { _ in Text("Apply".localizedFioriString()) }" + // sourcery: resultBuilder.defaultValue = "{ FioriButton { _ in Text("Apply".localizedFioriString()) } }" + var applyAction: FioriButton? { get } +} + +// sourcery: BaseComponent +protocol _SelectedEntriesSectionTitleComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "AttributedString("Selected".localizedFioriString())" + // sourcery: resultBuilder.defaultValue = "{ Text("Selected".localizedFioriString()) }" + var selectedEntriesSectionTitle: AttributedString? { get } +} + +// sourcery: BaseComponent +protocol _AllEntriesSectionTitleComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "AttributedString("All".localizedFioriString())" + // sourcery: resultBuilder.defaultValue = "{ Text("All".localizedFioriString()) }" + var allEntriesSectionTitle: AttributedString? { get } +} + +// sourcery: BaseComponent +protocol _SelectAllActionComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "FioriButton { _ in Text("Select All".localizedFioriString()) }" + // sourcery: resultBuilder.defaultValue = "{ FioriButton { _ in Text("Select All".localizedFioriString()) } }" + var selectAllAction: FioriButton? { get } +} + +// sourcery: BaseComponent +protocol _DeselectAllActionComponent { + // sourcery: @ViewBuilder + // sourcery: defaultValue = "FioriButton { _ in Text("Deselect All".localizedFioriString()) }" + // sourcery: resultBuilder.defaultValue = "{ FioriButton { _ in Text("Deselect All".localizedFioriString()) } }" + var deselectAllAction: FioriButton? { get } +} + +// sourcery: BaseComponent +protocol _ListPickerContentComponent { + @ViewBuilder + var listPickerContent: (() -> any View)? { get } +} diff --git a/Sources/FioriSwiftUICore/_ComponentProtocols/CompositeComponentProtocols.swift b/Sources/FioriSwiftUICore/_ComponentProtocols/CompositeComponentProtocols.swift index 3a96c4e38..099b902bd 100755 --- a/Sources/FioriSwiftUICore/_ComponentProtocols/CompositeComponentProtocols.swift +++ b/Sources/FioriSwiftUICore/_ComponentProtocols/CompositeComponentProtocols.swift @@ -569,3 +569,37 @@ protocol _DateTimePickerComponent: _TitleComponent, _ValueLabelComponent, _Manda // sourcery: CompositeComponent protocol _AvatarStackComponent: _AvatarsComponent, _AvatarsTitleComponent {} + +/// `ListPickerItem` is a view that provide a `NavigationLink` with a title and selected value. And `ListPickerDestination` is recommended to be used as its destination, which selection, search filter and customized rows are supported. +/// ## Usage +/// ```swift +/// let data = ["first", "second", "third"] +/// var body: some View { +/// ListPickerItem(title: { +/// Text("title") +/// }, value: { +/// Text("value") +/// }, axis: .vertical) { +/// ListPickerDestination(data, +/// id: \.self, +/// selection: $selection, +/// isTrackingLiveChanges: true, +/// searchFilter: { f, s in f.contains(s) }, rowContent: { +/// Text($0) +/// }) +/// } +/// } +/// ``` +// sourcery: CompositeComponent +protocol _ListPickerItemComponent: _TitleComponent, _ValueComponent { + // sourcery: defaultValue = .horizontal + var axis: Axis { get } + + @ViewBuilder + var destination: (() -> any View)? { get } +} + +/// `ListPickerDestination` is a view that provides a customizable list for `ListPickerItem` with selection, search filter and rows. +/// +// sourcery: CompositeComponent +protocol _ListPickerDestinationComponent: _CancelActionComponent, _ApplyActionComponent, _SelectedEntriesSectionTitleComponent, _SelectAllActionComponent, _DeselectAllActionComponent, _AllEntriesSectionTitleComponent, _ListPickerContentComponent {} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/AllEntriesSectionTitleStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/AllEntriesSectionTitleStyle.fiori.swift new file mode 100644 index 000000000..988b569c6 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/AllEntriesSectionTitleStyle.fiori.swift @@ -0,0 +1,20 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct AllEntriesSectionTitleBaseStyle: AllEntriesSectionTitleStyle { + @ViewBuilder + public func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> some View { + // Add default layout here + configuration.allEntriesSectionTitle + } +} + +// Default fiori styles +public struct AllEntriesSectionTitleFioriStyle: AllEntriesSectionTitleStyle { + @ViewBuilder + public func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> some View { + AllEntriesSectionTitle(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/ApplyActionStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/ApplyActionStyle.fiori.swift new file mode 100644 index 000000000..ce5ed2850 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/ApplyActionStyle.fiori.swift @@ -0,0 +1,19 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct ApplyActionBaseStyle: ApplyActionStyle { + @ViewBuilder + public func makeBody(_ configuration: ApplyActionConfiguration) -> some View { + configuration.applyAction + } +} + +// Default fiori styles +public struct ApplyActionFioriStyle: ApplyActionStyle { + @ViewBuilder + public func makeBody(_ configuration: ApplyActionConfiguration) -> some View { + ApplyAction(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/CancelActionStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/CancelActionStyle.fiori.swift new file mode 100644 index 000000000..8a0a39023 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/CancelActionStyle.fiori.swift @@ -0,0 +1,19 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct CancelActionBaseStyle: CancelActionStyle { + @ViewBuilder + public func makeBody(_ configuration: CancelActionConfiguration) -> some View { + configuration.cancelAction + } +} + +// Default fiori styles +public struct CancelActionFioriStyle: CancelActionStyle { + @ViewBuilder + public func makeBody(_ configuration: CancelActionConfiguration) -> some View { + CancelAction(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/DeselectAllActionStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/DeselectAllActionStyle.fiori.swift new file mode 100644 index 000000000..c9bec094e --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/DeselectAllActionStyle.fiori.swift @@ -0,0 +1,20 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct DeselectAllActionBaseStyle: DeselectAllActionStyle { + @ViewBuilder + public func makeBody(_ configuration: DeselectAllActionConfiguration) -> some View { + // Add default layout here + configuration.deselectAllAction + } +} + +// Default fiori styles +public struct DeselectAllActionFioriStyle: DeselectAllActionStyle { + @ViewBuilder + public func makeBody(_ configuration: DeselectAllActionConfiguration) -> some View { + DeselectAllAction(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/ListPickerContentStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerContentStyle.fiori.swift new file mode 100644 index 000000000..7d2bde2f0 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerContentStyle.fiori.swift @@ -0,0 +1,20 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct ListPickerContentBaseStyle: ListPickerContentStyle { + @ViewBuilder + public func makeBody(_ configuration: ListPickerContentConfiguration) -> some View { + // Add default layout here + configuration.listPickerContent + } +} + +// Default fiori styles +public struct ListPickerContentFioriStyle: ListPickerContentStyle { + @ViewBuilder + public func makeBody(_ configuration: ListPickerContentConfiguration) -> some View { + ListPickerContent(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/ListPickerDestinationStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerDestinationStyle.fiori.swift new file mode 100644 index 000000000..46afcf5c9 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerDestinationStyle.fiori.swift @@ -0,0 +1,738 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// swiftlint:disable file_length + +// Base Layout style +public struct ListPickerDestinationBaseStyle: ListPickerDestinationStyle { + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + configuration.listPickerContent + .listPickerDestinationConfiguration(configuration) + } +} + +// Default fiori styles +extension ListPickerDestinationFioriStyle { + struct ContentFioriStyle: ListPickerDestinationStyle { + func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + } + } + + struct CancelActionFioriStyle: CancelActionStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: CancelActionConfiguration) -> some View { + CancelAction(configuration) + .fioriButtonStyle(ListPickerDestinationButtonStyle(.navigation)) + .bold() + } + } + + struct ApplyActionFioriStyle: ApplyActionStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: ApplyActionConfiguration) -> some View { + ApplyAction(configuration) + .fioriButtonStyle(ListPickerDestinationButtonStyle(.navigation)) + } + } + + struct SelectedEntriesSectionTitleFioriStyle: SelectedEntriesSectionTitleStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + SelectedEntriesSectionTitle(configuration) + } + } + + struct SelectAllActionFioriStyle: SelectAllActionStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: SelectAllActionConfiguration) -> some View { + SelectAllAction(configuration) + .fioriButtonStyle(ListPickerDestinationButtonStyle()) + } + } + + struct DeselectAllActionFioriStyle: DeselectAllActionStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: DeselectAllActionConfiguration) -> some View { + DeselectAllAction(configuration) + .fioriButtonStyle(ListPickerDestinationButtonStyle()) + } + } + + struct AllEntriesSectionTitleFioriStyle: AllEntriesSectionTitleStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> some View { + AllEntriesSectionTitle(configuration) + } + } + + struct ListPickerContentFioriStyle: ListPickerContentStyle { + let listPickerDestinationConfiguration: ListPickerDestinationConfiguration + + func makeBody(_ configuration: ListPickerContentConfiguration) -> some View { + ListPickerContent(configuration) + } + } +} + +struct ListPickerDestinationButtonStyle: FioriButtonStyle { + enum ButtonPosition { + case navigation + case header + } + + let buttonPosition: ButtonPosition + + init(_ buttonPosition: ButtonPosition = .header) { + self.buttonPosition = buttonPosition + } + + func makeBody(configuration: Configuration) -> some View { + let font: Font + let foregroundColor: Color + + switch configuration.state { + case .normal: + foregroundColor = .preferredColor(.tintColor) + case .highlighted, .selected: + foregroundColor = .preferredColor(.tintColor3) + default: + foregroundColor = .preferredColor(.separator) + } + + switch self.buttonPosition { + case .navigation: + font = .fiori(forTextStyle: .body).weight(.bold) + case .header: + font = .fiori(forTextStyle: .subheadline) + } + let config = FioriButtonConfiguration(foregroundColor: foregroundColor, + backgroundColor: .clear, + font: font, + padding: EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0)) + return configuration.containerView(.unspecified) + .fioriButtonConfiguration(config) + } +} + +public extension ListPickerDestination { + /// Create a destination for `ListPickerItem`. + /// - Parameters: + /// - data: The data for constructing the list picker. + /// - 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. + /// - selections: A binding to a set which stores the selected items. + /// - isTrackingLiveChanges: A boolean value to indicate to track the changes live or not. + /// - searchFilter: The closure to filter the `data` in searching process. Request a boolean by the element and the filter key. + /// - rowContent: The view builder which returns the content of each row in the list picker. + init( + _ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selection: Binding, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> some View + ) { + let s = Binding>(get: { + if let s = selection.wrappedValue { + [s] + } else { + [] + } + }, set: { + selection.wrappedValue = $0.first + }) + let content = ListPickerDestinationContent( + data, + id: id, + children: children, + selections: s, + isSingleSelection: true, + allowEmpty: true, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent + ) + self.init { + FioriButton { _ in Text("Cancel".localizedFioriString()) } + } listPickerContent: { + content + } + } + + /// Create a destination for `ListPickerItem`. + /// - Parameters: + /// - data: The data for constructing the list picker. + /// - 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 an ID which stores the selected items. + /// - isTrackingLiveChanges: A boolean value to indicate to track the changes live or not. + /// - searchFilter: The closure to filter the `data` in searching process. Request a boolean by the element and the filter key. + /// - rowContent: The view builder which returns the content of each row in the list picker. + init( + _ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selection: Binding, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> some View + ) { + let s = Binding(get: { + Set([selection.wrappedValue]) + }, set: { + if let s = $0.first { + selection.wrappedValue = s + } else { + fatalError("Selection should not be empty.") + } + }) + + let content = ListPickerDestinationContent( + data, + id: id, + children: children, + selections: s, + isSingleSelection: true, + allowEmpty: false, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent + ) + self.init { + FioriButton { _ in Text("Cancel".localizedFioriString()) } + } listPickerContent: { + content + } + } + + /// Create a destination for `ListPickerItem`. + /// - Parameters: + /// - data: The data for constructing the list picker. + /// - 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. + /// - selections: A binding to a set which stores the selected items. + /// - isTrackingLiveChanges: A boolean value to indicate to track the changes live or not. + /// - searchFilter: The closure to filter the `data` in searching process. Request a boolean by the element and the filter key. + /// - rowContent: The view builder which returns the content of each row in the list picker. + init( + _ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selections: Binding?>, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> some View + ) { + let s = Binding(get: { + selections.wrappedValue ?? [] + }, set: { + selections.wrappedValue = $0 + }) + let content = ListPickerDestinationContent( + data, + id: id, + children: children, + selections: s, + isSingleSelection: false, + allowEmpty: true, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent + ) + self.init { + FioriButton { _ in Text("Cancel".localizedFioriString()) } + } listPickerContent: { + content + } + } + + /// Create a destination for `ListPickerItem`. + /// - Parameters: + /// - data: The data for constructing the list picker. + /// - 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. + /// - selections: A binding to a set which stores the non-optional selected items. + /// - allowEmpty: A boolean value to indicate to allow empty selections. + /// - isTrackingLiveChanges: A boolean value to indicate to track the changes live or not. + /// - searchFilter: The closure to filter the `data` in searching process. Request a boolean by the element and the filter key. + /// - rowContent: The view builder which returns the content of each row in the list picker. + init( + _ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selections: Binding>, + allowEmpty: Bool = true, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> some View + ) { + let content = ListPickerDestinationContent( + data, + id: id, + children: children, + selections: selections, + isSingleSelection: false, + allowEmpty: allowEmpty, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent + ) + self.init { + FioriButton { _ in Text("Cancel".localizedFioriString()) } + } listPickerContent: { + content + } + } +} + +public struct ListPickerDestinationContent: View { + @Environment(\.presentationMode) var presentationMode + @Environment(\.listPickerDestinationConfiguration) var destinationConfiguration + @Environment(\.disableEntriesSection) var disableEntriesSection + + @Binding private var selections: Set + private var isSingleSelection: Bool + private var allowEmpty: Bool + private var isTopLevel: Bool + + let data: Data + let id: KeyPath + let children: KeyPath? + let rowContent: (Data.Element) -> RowContent + let isTrackingLiveChanges: Bool + let searchFilter: ((Data.Element, String) -> Bool)? + + // MARK: - Internal state + + @State var selectionsPool: Set + @State var searchText = "" + @State var confirmationSelections: Bool = false + + init(_ data: Data, + id: KeyPath, + children: KeyPath?, + selections: Binding>, + isSingleSelection: Bool, + allowEmpty: Bool, + isTrackingLiveChanges: Bool, + searchFilter: ((Data.Element, String) -> Bool)?, + isTopLevel: Bool = true, + @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) + { + self.data = data + self.id = id + self.children = children + _selections = selections + self.isSingleSelection = isSingleSelection + self.allowEmpty = allowEmpty + self.isTrackingLiveChanges = isTrackingLiveChanges + self.searchFilter = searchFilter + + self.isTopLevel = isTopLevel + self.rowContent = rowContent + + if !isTrackingLiveChanges { + _selectionsPool = State(initialValue: selections.wrappedValue) + } else { + _selectionsPool = State(initialValue: []) + } + } + + public var body: some View { + Group { + if self.searchFilter != nil { + self.listContent() + .searchable(text: self.$searchText, placement: .navigationBarDrawer) + } else { + self.listContent() + } + } + .ifApply(!self.isTrackingLiveChanges && self.isTopLevel) { + $0.toolbar { + ToolbarItem(placement: .navigationBarLeading) { + self.destinationConfiguration?.cancelAction + .onSimultaneousTapGesture { + self.cancelActionTapped() + } + } + + ToolbarItem(placement: .navigationBarTrailing) { + self.destinationConfiguration?.applyAction + .onSimultaneousTapGesture { + self.confirm() + self.presentationMode.wrappedValue.dismiss() + } + .disabled(!self.allowEmpty && self.selectionsPool.isEmpty) + } + } + .confirmationDialog("Are you sure you want to discard your selections?".localizedFioriString(), + isPresented: self.$confirmationSelections, + titleVisibility: .visible, + actions: { + Button { + self.presentationMode.wrappedValue.dismiss() + } label: { + Text("Discard Changes".localizedFioriString()) + } + Button("Keep Editing".localizedFioriString(), role: .cancel) {} + }) + .navigationBarBackButtonHidden() + } + } + + func cancelActionTapped() { + if !(self.selections == self.selectionsPool) { + self.confirmationSelections.toggle() + } else { + self.presentationMode.wrappedValue.dismiss() + } + } + + private func selectedEntriesSectionHeaderIsEmpty() -> Bool { + (self.destinationConfiguration?.selectedEntriesSectionTitle.isEmpty ?? true) && + (self.destinationConfiguration?.deselectAllAction.isEmpty ?? true) + } + + private func allEntriesHeaderIsEmpty() -> Bool { + let isActionEmpty = (destinationConfiguration?.selectAllAction.isEmpty ?? true) && (self.destinationConfiguration?.deselectAllAction.isEmpty ?? true) + return (self.destinationConfiguration?.allEntriesSectionTitle.isEmpty ?? true) && isActionEmpty + } + + @ViewBuilder func listContent() -> some View { + List { + if self.isTopLevel, !self.disableEntriesSection, !self.isSingleSelection, self.destinationConfiguration != nil { + Section { + self.selectedSection() + } header: { + if !self.selectedEntriesSectionHeaderIsEmpty(), self.selectionsCount() > 0 { + HStack { + self.destinationConfiguration?.selectedEntriesSectionTitle + Spacer() + self.destinationConfiguration?.deselectAllAction + .onSimultaneousTapGesture { + self.deselectAll() + } + } + } + }.textCase(.none) + } + + Section { + ForEach(self.filteredDataOnPage(), id: self.id) { element in + Group { + let id_value = element[keyPath: id] + if let children, let childrenData = element[keyPath: children] { + ListPickerItem { + self.rowContent(element) + } value: { + EmptyView() + } destination: { + ListPickerDestinationContent(childrenData, + id: self.id, + children: children, + selections: self.isTrackingLiveChanges ? self.$selections : self.$selectionsPool, + isSingleSelection: self.isSingleSelection, + allowEmpty: self.allowEmpty, + isTrackingLiveChanges: true, + searchFilter: self.searchFilter, + isTopLevel: false, + rowContent: self.rowContent) + } + } else { + HStack { + self.rowContent(element) + Spacer().frame(minWidth: 0) + if self.isItemSelected(id_value) { + Image(systemName: "checkmark") + .foregroundColor(.preferredColor(.tintColor)) + } + } + .contentShape(Rectangle()) + .onTapGesture { + self.handleSelections(id_value) + } + } + } + } + } header: { + if !self.allEntriesHeaderIsEmpty(), !self.isSingleSelection { + HStack { + self.destinationConfiguration?.allEntriesSectionTitle + Spacer() + let selectionsCount = self.isTrackingLiveChanges ? self.selections.count : self.selectionsPool.count + if self.flattenData(data: self.data).count == selectionsCount { + self.destinationConfiguration?.deselectAllAction + .onSimultaneousTapGesture { + self.deselectAll() + } + } else { + self.destinationConfiguration?.selectAllAction + .onSimultaneousTapGesture { + self.selectAll() + } + } + } + } + }.textCase(.none) + } + } + + @ViewBuilder func selectedSection() -> some View { + let selectedData = selectedData() + ForEach(selectedData, id: self.id) { element in + let id_value = element[keyPath: id] + HStack { + self.rowContent(element) + Spacer().frame(minWidth: 0) + if self.isItemSelected(id_value) { + Image(systemName: "checkmark") + .foregroundColor(.preferredColor(.tintColor)) + } + } + .contentShape(Rectangle()) + .onTapGesture { + self.handleSelections(id_value) + } + } + } + + func selectedData() -> [Data.Element] { + let s = self.isTrackingLiveChanges ? self.selections : self.selectionsPool + return self.flattenData(data: self.data).filter { s.contains($0[keyPath: self.id]) } + } + + func flattenData(data: Data) -> [Data.Element] { + data.flatMap { element in + if let children, let childrenData = element[keyPath: children] { + return self.flattenData(data: childrenData) + } else { + return [element] + } + } + } + + func filteredDataOnPage() -> [Data.Element] { + self.data.filter { element in + if let searchFilter, !searchText.isEmpty { + return searchFilter(element, self.searchText) + } else { + return true + } + } + } + + func isItemSelected(_ idValue: ID) -> Bool { + if self.isTrackingLiveChanges { + return self.selections.contains(idValue) + } else { + return self.selectionsPool.contains(idValue) + } + } + + func handleSelections(_ idValue: ID) { + if self.isTrackingLiveChanges { + if self.selections.contains(idValue) { + if !self.allowEmpty, self.selectionsPool.count == 1 { + // should not remove the last selection + } else { + self.selections.remove(idValue) + } + } else { + if self.isSingleSelection { + self.selections = Set([idValue]) + } else { + self.selections.insert(idValue) + } + } + } else { + if self.selectionsPool.contains(idValue) { + if !self.allowEmpty, self.selectionsPool.count == 1 { + // should not remove the last selection + } else { + self.selectionsPool.remove(idValue) + } + } else { + if self.isSingleSelection { + self.selectionsPool = Set([idValue]) + } else { + self.selectionsPool.insert(idValue) + } + } + } + } + + func confirm() { + self.selections = self.selectionsPool + } + + func selectionsCount() -> Int { + self.isTrackingLiveChanges ? self.selections.count : self.selectionsPool.count + } + + func selectAll() { + if self.isTrackingLiveChanges { + self.selections = Set(self.flattenData(data: self.data).map { $0[keyPath: self.id] }) + } else { + self.selectionsPool = Set(self.flattenData(data: self.data).map { $0[keyPath: self.id] }) + } + } + + func deselectAll() { + if self.isTrackingLiveChanges { + self.selections.removeAll() + } else { + self.selectionsPool.removeAll() + } + } +} + +public extension ListPickerDestinationContent { + /// As content for `ListPickerDestination` + init(_ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selection: Binding, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) + { + let s = Binding>(get: { + if let s = selection.wrappedValue { + [s] + } else { + [] + } + }, set: { + selection.wrappedValue = $0.first + }) + self.init(data, + id: id, + children: children, + selections: s, + isSingleSelection: true, + allowEmpty: true, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent) + } + + /// As content for `ListPickerDestination` + init(_ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selection: Binding, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) + { + let s = Binding(get: { + Set([selection.wrappedValue]) + }, set: { + if let s = $0.first { + selection.wrappedValue = s + } else { + fatalError("Selection should not be empty.") + } + }) + self.init(data, + id: id, + children: children, + selections: s, + isSingleSelection: true, + allowEmpty: false, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent) + } + + /// As content for `ListPickerDestination` + init(_ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selections: Binding?>, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) + { + let s = Binding(get: { + selections.wrappedValue ?? [] + }, set: { + selections.wrappedValue = $0 + }) + self.init(data, + id: id, + children: children, + selections: s, + isSingleSelection: false, + allowEmpty: true, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent) + } + + /// As content for `ListPickerDestination` + init(_ data: Data, + id: KeyPath, + children: KeyPath? = nil, + selections: Binding>, + isTrackingLiveChanges: Bool = true, + searchFilter: ((Data.Element, String) -> Bool)? = nil, + @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) + { + self.init(data, + id: id, + children: children, + selections: selections, + isSingleSelection: false, + allowEmpty: true, + isTrackingLiveChanges: isTrackingLiveChanges, + searchFilter: searchFilter, + rowContent: rowContent) + } +} + +struct ListPickerDestinationConfigurationEnvironment: EnvironmentKey { + static let defaultValue: ListPickerDestinationConfiguration? = nil +} + +extension EnvironmentValues { + var listPickerDestinationConfiguration: ListPickerDestinationConfiguration? { + get { self[ListPickerDestinationConfigurationEnvironment.self] } + set { self[ListPickerDestinationConfigurationEnvironment.self] = newValue } + } +} + +extension View { + func listPickerDestinationConfiguration(_ configuration: ListPickerDestinationConfiguration) -> some View { + self.environment(\.listPickerDestinationConfiguration, configuration) + } +} + +struct DisableEntriesSectionEnvironment: EnvironmentKey { + static let defaultValue: Bool = false +} + +extension EnvironmentValues { + var disableEntriesSection: Bool { + get { self[DisableEntriesSectionEnvironment.self] } + set { self[DisableEntriesSectionEnvironment.self] = newValue } + } +} + +public extension View { + /// Adds a condition that controls whether entries section can be displayed for `ListPickerDestination`. + /// - Parameter disabled: A Boolean value that determines whether entries section can be displayed for `ListPickerDestination`. + /// - Returns: A view that controls whether entries section can be displayed for `ListPickerDestination`. + func disableEntriesSection(_ disabled: Bool = true) -> some View { + self.environment(\.disableEntriesSection, disabled) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/ListPickerItemStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerItemStyle.fiori.swift new file mode 100644 index 000000000..0b687a90b --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/ListPickerItemStyle.fiori.swift @@ -0,0 +1,53 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct ListPickerItemBaseStyle: ListPickerItemStyle { + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + NavigationLink { + configuration.destination + } label: { + switch configuration.axis { + case .horizontal: + HStack { + configuration.title + Spacer() + configuration.value + } + case .vertical: + CompactVStack(alignment: .leading) { + configuration.title + configuration.value + } + } + } + } +} + +// Default fiori styles +extension ListPickerItemFioriStyle { + struct ContentFioriStyle: ListPickerItemStyle { + func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + ListPickerItem(configuration) + } + } + + struct TitleFioriStyle: TitleStyle { + let listPickerItemConfiguration: ListPickerItemConfiguration + + func makeBody(_ configuration: TitleConfiguration) -> some View { + Title(configuration) + .font(.fiori(forTextStyle: .subheadline, weight: .bold)) + .foregroundColor(.preferredColor(.primaryLabel)) + } + } + + struct ValueFioriStyle: ValueStyle { + let listPickerItemConfiguration: ListPickerItemConfiguration + + func makeBody(_ configuration: ValueConfiguration) -> some View { + Value(configuration) + } + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/SelectAllActionStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/SelectAllActionStyle.fiori.swift new file mode 100644 index 000000000..8b705e8b6 --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/SelectAllActionStyle.fiori.swift @@ -0,0 +1,20 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct SelectAllActionBaseStyle: SelectAllActionStyle { + @ViewBuilder + public func makeBody(_ configuration: SelectAllActionConfiguration) -> some View { + // Add default layout here + configuration.selectAllAction + } +} + +// Default fiori styles +public struct SelectAllActionFioriStyle: SelectAllActionStyle { + @ViewBuilder + public func makeBody(_ configuration: SelectAllActionConfiguration) -> some View { + SelectAllAction(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/SelectedEntriesSectionTitleStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/SelectedEntriesSectionTitleStyle.fiori.swift new file mode 100644 index 000000000..a1298bf8c --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/SelectedEntriesSectionTitleStyle.fiori.swift @@ -0,0 +1,20 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct SelectedEntriesSectionTitleBaseStyle: SelectedEntriesSectionTitleStyle { + @ViewBuilder + public func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + // Add default layout here + configuration.selectedEntriesSectionTitle + } +} + +// Default fiori styles +public struct SelectedEntriesSectionTitleFioriStyle: SelectedEntriesSectionTitleStyle { + @ViewBuilder + public func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + SelectedEntriesSectionTitle(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_FioriStyles/ValueStyle.fiori.swift b/Sources/FioriSwiftUICore/_FioriStyles/ValueStyle.fiori.swift new file mode 100644 index 000000000..e90c3c62f --- /dev/null +++ b/Sources/FioriSwiftUICore/_FioriStyles/ValueStyle.fiori.swift @@ -0,0 +1,19 @@ +import FioriThemeManager +import Foundation +import SwiftUI + +// Base Layout style +public struct ValueBaseStyle: ValueStyle { + @ViewBuilder + public func makeBody(_ configuration: ValueConfiguration) -> some View { + configuration.value + } +} + +// Default fiori styles +public struct ValueFioriStyle: ValueStyle { + @ViewBuilder + public func makeBody(_ configuration: ValueConfiguration) -> some View { + Value(configuration) + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitle.generated.swift new file mode 100644 index 000000000..7f261bf40 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitle.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct AllEntriesSectionTitle { + let allEntriesSectionTitle: any View + + @Environment(\.allEntriesSectionTitleStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder allEntriesSectionTitle: () -> any View = { Text("All".localizedFioriString()) }) { + self.allEntriesSectionTitle = allEntriesSectionTitle() + } +} + +public extension AllEntriesSectionTitle { + init(allEntriesSectionTitle: AttributedString? = AttributedString("All".localizedFioriString())) { + self.init(allEntriesSectionTitle: { OptionalText(allEntriesSectionTitle) }) + } +} + +public extension AllEntriesSectionTitle { + init(_ configuration: AllEntriesSectionTitleConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: AllEntriesSectionTitleConfiguration, shouldApplyDefaultStyle: Bool) { + self.allEntriesSectionTitle = configuration.allEntriesSectionTitle + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension AllEntriesSectionTitle: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(allEntriesSectionTitle: .init(self.allEntriesSectionTitle))).typeErased + .transformEnvironment(\.allEntriesSectionTitleStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension AllEntriesSectionTitle { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + AllEntriesSectionTitle(.init(allEntriesSectionTitle: .init(self.allEntriesSectionTitle))) + .shouldApplyDefaultStyle(false) + .allEntriesSectionTitleStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitleStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitleStyle.generated.swift new file mode 100644 index 000000000..382f9ef02 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/AllEntriesSectionTitle/AllEntriesSectionTitleStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol AllEntriesSectionTitleStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> Body +} + +struct AnyAllEntriesSectionTitleStyle: AllEntriesSectionTitleStyle { + let content: (AllEntriesSectionTitleConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (AllEntriesSectionTitleConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct AllEntriesSectionTitleConfiguration { + public let allEntriesSectionTitle: AllEntriesSectionTitle + + public typealias AllEntriesSectionTitle = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyAction.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyAction.generated.swift new file mode 100644 index 000000000..dbc29d138 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyAction.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct ApplyAction { + let applyAction: any View + + @Environment(\.applyActionStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder applyAction: () -> any View = { FioriButton { _ in Text("Apply".localizedFioriString()) } }) { + self.applyAction = applyAction() + } +} + +public extension ApplyAction { + init(applyAction: FioriButton? = FioriButton { _ in Text("Apply".localizedFioriString()) }) { + self.init(applyAction: { applyAction }) + } +} + +public extension ApplyAction { + init(_ configuration: ApplyActionConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: ApplyActionConfiguration, shouldApplyDefaultStyle: Bool) { + self.applyAction = configuration.applyAction + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension ApplyAction: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(applyAction: .init(self.applyAction))).typeErased + .transformEnvironment(\.applyActionStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension ApplyAction { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + ApplyAction(.init(applyAction: .init(self.applyAction))) + .shouldApplyDefaultStyle(false) + .applyActionStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyActionStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyActionStyle.generated.swift new file mode 100644 index 000000000..1bf8758b3 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ApplyAction/ApplyActionStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol ApplyActionStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: ApplyActionConfiguration) -> Body +} + +struct AnyApplyActionStyle: ApplyActionStyle { + let content: (ApplyActionConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (ApplyActionConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: ApplyActionConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct ApplyActionConfiguration { + public let applyAction: ApplyAction + + public typealias ApplyAction = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelAction.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelAction.generated.swift new file mode 100644 index 000000000..0d415faad --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelAction.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct CancelAction { + let cancelAction: any View + + @Environment(\.cancelActionStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder cancelAction: () -> any View = { FioriButton { _ in Text("Cancel".localizedFioriString()) } }) { + self.cancelAction = cancelAction() + } +} + +public extension CancelAction { + init(cancelAction: FioriButton? = FioriButton { _ in Text("Cancel".localizedFioriString()) }) { + self.init(cancelAction: { cancelAction }) + } +} + +public extension CancelAction { + init(_ configuration: CancelActionConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: CancelActionConfiguration, shouldApplyDefaultStyle: Bool) { + self.cancelAction = configuration.cancelAction + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension CancelAction: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(cancelAction: .init(self.cancelAction))).typeErased + .transformEnvironment(\.cancelActionStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension CancelAction { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + CancelAction(.init(cancelAction: .init(self.cancelAction))) + .shouldApplyDefaultStyle(false) + .cancelActionStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelActionStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelActionStyle.generated.swift new file mode 100644 index 000000000..47e737d33 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/CancelAction/CancelActionStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol CancelActionStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: CancelActionConfiguration) -> Body +} + +struct AnyCancelActionStyle: CancelActionStyle { + let content: (CancelActionConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (CancelActionConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: CancelActionConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct CancelActionConfiguration { + public let cancelAction: CancelAction + + public typealias CancelAction = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllAction.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllAction.generated.swift new file mode 100644 index 000000000..fe3fa350a --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllAction.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct DeselectAllAction { + let deselectAllAction: any View + + @Environment(\.deselectAllActionStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder deselectAllAction: () -> any View = { FioriButton { _ in Text("Deselect All".localizedFioriString()) } }) { + self.deselectAllAction = deselectAllAction() + } +} + +public extension DeselectAllAction { + init(deselectAllAction: FioriButton? = FioriButton { _ in Text("Deselect All".localizedFioriString()) }) { + self.init(deselectAllAction: { deselectAllAction }) + } +} + +public extension DeselectAllAction { + init(_ configuration: DeselectAllActionConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: DeselectAllActionConfiguration, shouldApplyDefaultStyle: Bool) { + self.deselectAllAction = configuration.deselectAllAction + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension DeselectAllAction: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(deselectAllAction: .init(self.deselectAllAction))).typeErased + .transformEnvironment(\.deselectAllActionStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension DeselectAllAction { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + DeselectAllAction(.init(deselectAllAction: .init(self.deselectAllAction))) + .shouldApplyDefaultStyle(false) + .deselectAllActionStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllActionStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllActionStyle.generated.swift new file mode 100644 index 000000000..e43e8742c --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/DeselectAllAction/DeselectAllActionStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol DeselectAllActionStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: DeselectAllActionConfiguration) -> Body +} + +struct AnyDeselectAllActionStyle: DeselectAllActionStyle { + let content: (DeselectAllActionConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (DeselectAllActionConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: DeselectAllActionConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct DeselectAllActionConfiguration { + public let deselectAllAction: DeselectAllAction + + public typealias DeselectAllAction = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContent.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContent.generated.swift new file mode 100644 index 000000000..10b11cc91 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContent.generated.swift @@ -0,0 +1,57 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct ListPickerContent { + let listPickerContent: any View + + @Environment(\.listPickerContentStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder listPickerContent: () -> any View = { EmptyView() }) { + self.listPickerContent = listPickerContent() + } +} + +public extension ListPickerContent { + init(_ configuration: ListPickerContentConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: ListPickerContentConfiguration, shouldApplyDefaultStyle: Bool) { + self.listPickerContent = configuration.listPickerContent + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension ListPickerContent: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(listPickerContent: .init(self.listPickerContent))).typeErased + .transformEnvironment(\.listPickerContentStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension ListPickerContent { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + ListPickerContent(.init(listPickerContent: .init(self.listPickerContent))) + .shouldApplyDefaultStyle(false) + .listPickerContentStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContentStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContentStyle.generated.swift new file mode 100644 index 000000000..fb1cb0093 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerContent/ListPickerContentStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol ListPickerContentStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: ListPickerContentConfiguration) -> Body +} + +struct AnyListPickerContentStyle: ListPickerContentStyle { + let content: (ListPickerContentConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (ListPickerContentConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: ListPickerContentConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct ListPickerContentConfiguration { + public let listPickerContent: ListPickerContent + + public typealias ListPickerContent = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestination.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestination.generated.swift new file mode 100644 index 000000000..fd9e57009 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestination.generated.swift @@ -0,0 +1,97 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +/// `ListPickerDestination` is a view that provides a customizable list for `ListPickerItem` with selection, search filter and rows. +/// +public struct ListPickerDestination { + let cancelAction: any View + let applyAction: any View + let selectedEntriesSectionTitle: any View + let selectAllAction: any View + let deselectAllAction: any View + let allEntriesSectionTitle: any View + let listPickerContent: any View + + @Environment(\.listPickerDestinationStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder cancelAction: () -> any View = { FioriButton { _ in Text("Cancel".localizedFioriString()) } }, + @ViewBuilder applyAction: () -> any View = { FioriButton { _ in Text("Apply".localizedFioriString()) } }, + @ViewBuilder selectedEntriesSectionTitle: () -> any View = { Text("Selected".localizedFioriString()) }, + @ViewBuilder selectAllAction: () -> any View = { FioriButton { _ in Text("Select All".localizedFioriString()) } }, + @ViewBuilder deselectAllAction: () -> any View = { FioriButton { _ in Text("Deselect All".localizedFioriString()) } }, + @ViewBuilder allEntriesSectionTitle: () -> any View = { Text("All".localizedFioriString()) }, + @ViewBuilder listPickerContent: () -> any View = { EmptyView() }) + { + self.cancelAction = CancelAction(cancelAction: cancelAction) + self.applyAction = ApplyAction(applyAction: applyAction) + self.selectedEntriesSectionTitle = SelectedEntriesSectionTitle(selectedEntriesSectionTitle: selectedEntriesSectionTitle) + self.selectAllAction = SelectAllAction(selectAllAction: selectAllAction) + self.deselectAllAction = DeselectAllAction(deselectAllAction: deselectAllAction) + self.allEntriesSectionTitle = AllEntriesSectionTitle(allEntriesSectionTitle: allEntriesSectionTitle) + self.listPickerContent = ListPickerContent(listPickerContent: listPickerContent) + } +} + +public extension ListPickerDestination { + init(cancelAction: FioriButton? = FioriButton { _ in Text("Cancel".localizedFioriString()) }, + applyAction: FioriButton? = FioriButton { _ in Text("Apply".localizedFioriString()) }, + selectedEntriesSectionTitle: AttributedString? = AttributedString("Selected".localizedFioriString()), + selectAllAction: FioriButton? = FioriButton { _ in Text("Select All".localizedFioriString()) }, + deselectAllAction: FioriButton? = FioriButton { _ in Text("Deselect All".localizedFioriString()) }, + allEntriesSectionTitle: AttributedString? = AttributedString("All".localizedFioriString()), + @ViewBuilder listPickerContent: () -> any View = { EmptyView() }) + { + self.init(cancelAction: { cancelAction }, applyAction: { applyAction }, selectedEntriesSectionTitle: { OptionalText(selectedEntriesSectionTitle) }, selectAllAction: { selectAllAction }, deselectAllAction: { deselectAllAction }, allEntriesSectionTitle: { OptionalText(allEntriesSectionTitle) }, listPickerContent: listPickerContent) + } +} + +public extension ListPickerDestination { + init(_ configuration: ListPickerDestinationConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: ListPickerDestinationConfiguration, shouldApplyDefaultStyle: Bool) { + self.cancelAction = configuration.cancelAction + self.applyAction = configuration.applyAction + self.selectedEntriesSectionTitle = configuration.selectedEntriesSectionTitle + self.selectAllAction = configuration.selectAllAction + self.deselectAllAction = configuration.deselectAllAction + self.allEntriesSectionTitle = configuration.allEntriesSectionTitle + self.listPickerContent = configuration.listPickerContent + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension ListPickerDestination: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(cancelAction: .init(self.cancelAction), applyAction: .init(self.applyAction), selectedEntriesSectionTitle: .init(self.selectedEntriesSectionTitle), selectAllAction: .init(self.selectAllAction), deselectAllAction: .init(self.deselectAllAction), allEntriesSectionTitle: .init(self.allEntriesSectionTitle), listPickerContent: .init(self.listPickerContent))).typeErased + .transformEnvironment(\.listPickerDestinationStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension ListPickerDestination { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + ListPickerDestination(.init(cancelAction: .init(self.cancelAction), applyAction: .init(self.applyAction), selectedEntriesSectionTitle: .init(self.selectedEntriesSectionTitle), selectAllAction: .init(self.selectAllAction), deselectAllAction: .init(self.deselectAllAction), allEntriesSectionTitle: .init(self.allEntriesSectionTitle), listPickerContent: .init(self.listPickerContent))) + .shouldApplyDefaultStyle(false) + .listPickerDestinationStyle(ListPickerDestinationFioriStyle.ContentFioriStyle()) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestinationStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestinationStyle.generated.swift new file mode 100644 index 000000000..05b19d3b6 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerDestination/ListPickerDestinationStyle.generated.swift @@ -0,0 +1,53 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol ListPickerDestinationStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: ListPickerDestinationConfiguration) -> Body +} + +struct AnyListPickerDestinationStyle: ListPickerDestinationStyle { + let content: (ListPickerDestinationConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (ListPickerDestinationConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct ListPickerDestinationConfiguration { + public let cancelAction: CancelAction + public let applyAction: ApplyAction + public let selectedEntriesSectionTitle: SelectedEntriesSectionTitle + public let selectAllAction: SelectAllAction + public let deselectAllAction: DeselectAllAction + public let allEntriesSectionTitle: AllEntriesSectionTitle + public let listPickerContent: ListPickerContent + + public typealias CancelAction = ConfigurationViewWrapper + public typealias ApplyAction = ConfigurationViewWrapper + public typealias SelectedEntriesSectionTitle = ConfigurationViewWrapper + public typealias SelectAllAction = ConfigurationViewWrapper + public typealias DeselectAllAction = ConfigurationViewWrapper + public typealias AllEntriesSectionTitle = ConfigurationViewWrapper + public typealias ListPickerContent = ConfigurationViewWrapper +} + +public struct ListPickerDestinationFioriStyle: ListPickerDestinationStyle { + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .cancelActionStyle(CancelActionFioriStyle(listPickerDestinationConfiguration: configuration)) + .applyActionStyle(ApplyActionFioriStyle(listPickerDestinationConfiguration: configuration)) + .selectedEntriesSectionTitleStyle(SelectedEntriesSectionTitleFioriStyle(listPickerDestinationConfiguration: configuration)) + .selectAllActionStyle(SelectAllActionFioriStyle(listPickerDestinationConfiguration: configuration)) + .deselectAllActionStyle(DeselectAllActionFioriStyle(listPickerDestinationConfiguration: configuration)) + .allEntriesSectionTitleStyle(AllEntriesSectionTitleFioriStyle(listPickerDestinationConfiguration: configuration)) + .listPickerContentStyle(ListPickerContentFioriStyle(listPickerDestinationConfiguration: configuration)) + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItem.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItem.generated.swift new file mode 100644 index 000000000..be205f8ba --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItem.generated.swift @@ -0,0 +1,100 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +/// `ListPickerItem` is a view that provide a `NavigationLink` with a title and selected value. And `ListPickerDestination` is recommended to be used as its destination, which selection, search filter and customized rows are supported. +/// ## Usage +/// ```swift +/// let data = ["first", "second", "third"] +/// var body: some View { +/// ListPickerItem(title: { +/// Text("title") +/// }, value: { +/// Text("value") +/// }, axis: .vertical) { +/// ListPickerDestination(data, +/// id: \.self, +/// selection: $selection, +/// isTrackingLiveChanges: true, +/// searchFilter: { f, s in f.contains(s) }, rowContent: { +/// Text($0) +/// }) +/// } +/// } +/// ``` +public struct ListPickerItem { + let title: any View + let value: any View + let axis: Axis + let destination: any View + + @Environment(\.listPickerItemStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder title: () -> any View, + @ViewBuilder value: () -> any View = { EmptyView() }, + axis: Axis = .horizontal, + @ViewBuilder destination: () -> any View = { EmptyView() }) + { + self.title = Title(title: title) + self.value = Value(value: value) + self.axis = axis + self.destination = destination() + } +} + +public extension ListPickerItem { + init(title: AttributedString, + value: AttributedString? = nil, + axis: Axis = .horizontal, + @ViewBuilder destination: () -> any View = { EmptyView() }) + { + self.init(title: { Text(title) }, value: { OptionalText(value) }, axis: axis, destination: destination) + } +} + +public extension ListPickerItem { + init(_ configuration: ListPickerItemConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: ListPickerItemConfiguration, shouldApplyDefaultStyle: Bool) { + self.title = configuration.title + self.value = configuration.value + self.axis = configuration.axis + self.destination = configuration.destination + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension ListPickerItem: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(title: .init(self.title), value: .init(self.value), axis: self.axis, destination: .init(self.destination))).typeErased + .transformEnvironment(\.listPickerItemStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension ListPickerItem { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + ListPickerItem(.init(title: .init(self.title), value: .init(self.value), axis: self.axis, destination: .init(self.destination))) + .shouldApplyDefaultStyle(false) + .listPickerItemStyle(ListPickerItemFioriStyle.ContentFioriStyle()) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItemStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItemStyle.generated.swift new file mode 100644 index 000000000..c42d0f3bf --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/ListPickerItem/ListPickerItemStyle.generated.swift @@ -0,0 +1,41 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol ListPickerItemStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: ListPickerItemConfiguration) -> Body +} + +struct AnyListPickerItemStyle: ListPickerItemStyle { + let content: (ListPickerItemConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (ListPickerItemConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct ListPickerItemConfiguration { + public let title: Title + public let value: Value + public let axis: Axis + public let destination: Destination + + public typealias Title = ConfigurationViewWrapper + public typealias Value = ConfigurationViewWrapper + public typealias Destination = ConfigurationViewWrapper +} + +public struct ListPickerItemFioriStyle: ListPickerItemStyle { + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + ListPickerItem(configuration) + .titleStyle(TitleFioriStyle(listPickerItemConfiguration: configuration)) + .valueStyle(ValueFioriStyle(listPickerItemConfiguration: configuration)) + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllAction.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllAction.generated.swift new file mode 100644 index 000000000..54544ca36 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllAction.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct SelectAllAction { + let selectAllAction: any View + + @Environment(\.selectAllActionStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder selectAllAction: () -> any View = { FioriButton { _ in Text("Select All".localizedFioriString()) } }) { + self.selectAllAction = selectAllAction() + } +} + +public extension SelectAllAction { + init(selectAllAction: FioriButton? = FioriButton { _ in Text("Select All".localizedFioriString()) }) { + self.init(selectAllAction: { selectAllAction }) + } +} + +public extension SelectAllAction { + init(_ configuration: SelectAllActionConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: SelectAllActionConfiguration, shouldApplyDefaultStyle: Bool) { + self.selectAllAction = configuration.selectAllAction + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension SelectAllAction: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(selectAllAction: .init(self.selectAllAction))).typeErased + .transformEnvironment(\.selectAllActionStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension SelectAllAction { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + SelectAllAction(.init(selectAllAction: .init(self.selectAllAction))) + .shouldApplyDefaultStyle(false) + .selectAllActionStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllActionStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllActionStyle.generated.swift new file mode 100644 index 000000000..d55f631e5 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectAllAction/SelectAllActionStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol SelectAllActionStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: SelectAllActionConfiguration) -> Body +} + +struct AnySelectAllActionStyle: SelectAllActionStyle { + let content: (SelectAllActionConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (SelectAllActionConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: SelectAllActionConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct SelectAllActionConfiguration { + public let selectAllAction: SelectAllAction + + public typealias SelectAllAction = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitle.generated.swift new file mode 100644 index 000000000..8e2f21dbb --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitle.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct SelectedEntriesSectionTitle { + let selectedEntriesSectionTitle: any View + + @Environment(\.selectedEntriesSectionTitleStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder selectedEntriesSectionTitle: () -> any View = { Text("Selected".localizedFioriString()) }) { + self.selectedEntriesSectionTitle = selectedEntriesSectionTitle() + } +} + +public extension SelectedEntriesSectionTitle { + init(selectedEntriesSectionTitle: AttributedString? = AttributedString("Selected".localizedFioriString())) { + self.init(selectedEntriesSectionTitle: { OptionalText(selectedEntriesSectionTitle) }) + } +} + +public extension SelectedEntriesSectionTitle { + init(_ configuration: SelectedEntriesSectionTitleConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: SelectedEntriesSectionTitleConfiguration, shouldApplyDefaultStyle: Bool) { + self.selectedEntriesSectionTitle = configuration.selectedEntriesSectionTitle + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension SelectedEntriesSectionTitle: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(selectedEntriesSectionTitle: .init(self.selectedEntriesSectionTitle))).typeErased + .transformEnvironment(\.selectedEntriesSectionTitleStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension SelectedEntriesSectionTitle { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + SelectedEntriesSectionTitle(.init(selectedEntriesSectionTitle: .init(self.selectedEntriesSectionTitle))) + .shouldApplyDefaultStyle(false) + .selectedEntriesSectionTitleStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitleStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitleStyle.generated.swift new file mode 100644 index 000000000..53ee262e2 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/SelectedEntriesSectionTitle/SelectedEntriesSectionTitleStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol SelectedEntriesSectionTitleStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> Body +} + +struct AnySelectedEntriesSectionTitleStyle: SelectedEntriesSectionTitleStyle { + let content: (SelectedEntriesSectionTitleConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (SelectedEntriesSectionTitleConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct SelectedEntriesSectionTitleConfiguration { + public let selectedEntriesSectionTitle: SelectedEntriesSectionTitle + + public typealias SelectedEntriesSectionTitle = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/Value.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/Value.generated.swift new file mode 100644 index 000000000..bd48e2850 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/Value.generated.swift @@ -0,0 +1,63 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public struct Value { + let value: any View + + @Environment(\.valueStyle) var style + + fileprivate var _shouldApplyDefaultStyle = true + + public init(@ViewBuilder value: () -> any View = { EmptyView() }) { + self.value = value() + } +} + +public extension Value { + init(value: AttributedString? = nil) { + self.init(value: { OptionalText(value) }) + } +} + +public extension Value { + init(_ configuration: ValueConfiguration) { + self.init(configuration, shouldApplyDefaultStyle: false) + } + + internal init(_ configuration: ValueConfiguration, shouldApplyDefaultStyle: Bool) { + self.value = configuration.value + self._shouldApplyDefaultStyle = shouldApplyDefaultStyle + } +} + +extension Value: View { + public var body: some View { + if self._shouldApplyDefaultStyle { + self.defaultStyle() + } else { + self.style.resolve(configuration: .init(value: .init(self.value))).typeErased + .transformEnvironment(\.valueStyleStack) { stack in + if !stack.isEmpty { + stack.removeLast() + } + } + } + } +} + +private extension Value { + func shouldApplyDefaultStyle(_ bool: Bool) -> some View { + var s = self + s._shouldApplyDefaultStyle = bool + return s + } + + func defaultStyle() -> some View { + Value(.init(value: .init(self.value))) + .shouldApplyDefaultStyle(false) + .valueStyle(.fiori) + .typeErased + } +} diff --git a/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/ValueStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/ValueStyle.generated.swift new file mode 100644 index 000000000..a7958e8f0 --- /dev/null +++ b/Sources/FioriSwiftUICore/_generated/StyleableComponents/Value/ValueStyle.generated.swift @@ -0,0 +1,28 @@ +// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT +import Foundation +import SwiftUI + +public protocol ValueStyle: DynamicProperty { + associatedtype Body: View + + func makeBody(_ configuration: ValueConfiguration) -> Body +} + +struct AnyValueStyle: ValueStyle { + let content: (ValueConfiguration) -> any View + + init(@ViewBuilder _ content: @escaping (ValueConfiguration) -> any View) { + self.content = content + } + + public func makeBody(_ configuration: ValueConfiguration) -> some View { + self.content(configuration).typeErased + } +} + +public struct ValueConfiguration { + public let value: Value + + public typealias Value = ConfigurationViewWrapper +} diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ComponentStyleProtocol+Extension.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ComponentStyleProtocol+Extension.generated.swift index 4c7b02541..ffab304d6 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ComponentStyleProtocol+Extension.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ComponentStyleProtocol+Extension.generated.swift @@ -31,6 +31,34 @@ public extension ActionStyle where Self == ActionFioriStyle { } } +// MARK: AllEntriesSectionTitleStyle + +public extension AllEntriesSectionTitleStyle where Self == AllEntriesSectionTitleBaseStyle { + static var base: AllEntriesSectionTitleBaseStyle { + AllEntriesSectionTitleBaseStyle() + } +} + +public extension AllEntriesSectionTitleStyle where Self == AllEntriesSectionTitleFioriStyle { + static var fiori: AllEntriesSectionTitleFioriStyle { + AllEntriesSectionTitleFioriStyle() + } +} + +// MARK: ApplyActionStyle + +public extension ApplyActionStyle where Self == ApplyActionBaseStyle { + static var base: ApplyActionBaseStyle { + ApplyActionBaseStyle() + } +} + +public extension ApplyActionStyle where Self == ApplyActionFioriStyle { + static var fiori: ApplyActionFioriStyle { + ApplyActionFioriStyle() + } +} + // MARK: AttributeStyle public extension AttributeStyle where Self == AttributeBaseStyle { @@ -227,6 +255,20 @@ public extension BannerMessageStyle where Self == BannerMessageTopDividerStyle { } } +// MARK: CancelActionStyle + +public extension CancelActionStyle where Self == CancelActionBaseStyle { + static var base: CancelActionBaseStyle { + CancelActionBaseStyle() + } +} + +public extension CancelActionStyle where Self == CancelActionFioriStyle { + static var fiori: CancelActionFioriStyle { + CancelActionFioriStyle() + } +} + // MARK: CardBodyStyle public extension CardBodyStyle where Self == CardBodyBaseStyle { @@ -1711,6 +1753,20 @@ public extension DescriptionStyle where Self == DescriptionFioriStyle { } } +// MARK: DeselectAllActionStyle + +public extension DeselectAllActionStyle where Self == DeselectAllActionBaseStyle { + static var base: DeselectAllActionBaseStyle { + DeselectAllActionBaseStyle() + } +} + +public extension DeselectAllActionStyle where Self == DeselectAllActionFioriStyle { + static var fiori: DeselectAllActionFioriStyle { + DeselectAllActionFioriStyle() + } +} + // MARK: DetailImageStyle public extension DetailImageStyle where Self == DetailImageBaseStyle { @@ -2481,6 +2537,237 @@ public extension LinearProgressIndicatorViewStyle where Self == LinearProgressIn } } +// MARK: ListPickerContentStyle + +public extension ListPickerContentStyle where Self == ListPickerContentBaseStyle { + static var base: ListPickerContentBaseStyle { + ListPickerContentBaseStyle() + } +} + +public extension ListPickerContentStyle where Self == ListPickerContentFioriStyle { + static var fiori: ListPickerContentFioriStyle { + ListPickerContentFioriStyle() + } +} + +// MARK: ListPickerDestinationStyle + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationBaseStyle { + static var base: ListPickerDestinationBaseStyle { + ListPickerDestinationBaseStyle() + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationFioriStyle { + static var fiori: ListPickerDestinationFioriStyle { + ListPickerDestinationFioriStyle() + } +} + +public struct ListPickerDestinationCancelActionStyle: ListPickerDestinationStyle { + let style: any CancelActionStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .cancelActionStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationCancelActionStyle { + static func cancelActionStyle(_ style: some CancelActionStyle) -> ListPickerDestinationCancelActionStyle { + ListPickerDestinationCancelActionStyle(style: style) + } + + static func cancelActionStyle(@ViewBuilder content: @escaping (CancelActionConfiguration) -> some View) -> ListPickerDestinationCancelActionStyle { + let style = AnyCancelActionStyle(content) + return ListPickerDestinationCancelActionStyle(style: style) + } +} + +public struct ListPickerDestinationApplyActionStyle: ListPickerDestinationStyle { + let style: any ApplyActionStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .applyActionStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationApplyActionStyle { + static func applyActionStyle(_ style: some ApplyActionStyle) -> ListPickerDestinationApplyActionStyle { + ListPickerDestinationApplyActionStyle(style: style) + } + + static func applyActionStyle(@ViewBuilder content: @escaping (ApplyActionConfiguration) -> some View) -> ListPickerDestinationApplyActionStyle { + let style = AnyApplyActionStyle(content) + return ListPickerDestinationApplyActionStyle(style: style) + } +} + +public struct ListPickerDestinationSelectedEntriesSectionTitleStyle: ListPickerDestinationStyle { + let style: any SelectedEntriesSectionTitleStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .selectedEntriesSectionTitleStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationSelectedEntriesSectionTitleStyle { + static func selectedEntriesSectionTitleStyle(_ style: some SelectedEntriesSectionTitleStyle) -> ListPickerDestinationSelectedEntriesSectionTitleStyle { + ListPickerDestinationSelectedEntriesSectionTitleStyle(style: style) + } + + static func selectedEntriesSectionTitleStyle(@ViewBuilder content: @escaping (SelectedEntriesSectionTitleConfiguration) -> some View) -> ListPickerDestinationSelectedEntriesSectionTitleStyle { + let style = AnySelectedEntriesSectionTitleStyle(content) + return ListPickerDestinationSelectedEntriesSectionTitleStyle(style: style) + } +} + +public struct ListPickerDestinationSelectAllActionStyle: ListPickerDestinationStyle { + let style: any SelectAllActionStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .selectAllActionStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationSelectAllActionStyle { + static func selectAllActionStyle(_ style: some SelectAllActionStyle) -> ListPickerDestinationSelectAllActionStyle { + ListPickerDestinationSelectAllActionStyle(style: style) + } + + static func selectAllActionStyle(@ViewBuilder content: @escaping (SelectAllActionConfiguration) -> some View) -> ListPickerDestinationSelectAllActionStyle { + let style = AnySelectAllActionStyle(content) + return ListPickerDestinationSelectAllActionStyle(style: style) + } +} + +public struct ListPickerDestinationDeselectAllActionStyle: ListPickerDestinationStyle { + let style: any DeselectAllActionStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .deselectAllActionStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationDeselectAllActionStyle { + static func deselectAllActionStyle(_ style: some DeselectAllActionStyle) -> ListPickerDestinationDeselectAllActionStyle { + ListPickerDestinationDeselectAllActionStyle(style: style) + } + + static func deselectAllActionStyle(@ViewBuilder content: @escaping (DeselectAllActionConfiguration) -> some View) -> ListPickerDestinationDeselectAllActionStyle { + let style = AnyDeselectAllActionStyle(content) + return ListPickerDestinationDeselectAllActionStyle(style: style) + } +} + +public struct ListPickerDestinationAllEntriesSectionTitleStyle: ListPickerDestinationStyle { + let style: any AllEntriesSectionTitleStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .allEntriesSectionTitleStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationAllEntriesSectionTitleStyle { + static func allEntriesSectionTitleStyle(_ style: some AllEntriesSectionTitleStyle) -> ListPickerDestinationAllEntriesSectionTitleStyle { + ListPickerDestinationAllEntriesSectionTitleStyle(style: style) + } + + static func allEntriesSectionTitleStyle(@ViewBuilder content: @escaping (AllEntriesSectionTitleConfiguration) -> some View) -> ListPickerDestinationAllEntriesSectionTitleStyle { + let style = AnyAllEntriesSectionTitleStyle(content) + return ListPickerDestinationAllEntriesSectionTitleStyle(style: style) + } +} + +public struct ListPickerDestinationListPickerContentStyle: ListPickerDestinationStyle { + let style: any ListPickerContentStyle + + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .listPickerContentStyle(self.style) + .typeErased + } +} + +public extension ListPickerDestinationStyle where Self == ListPickerDestinationListPickerContentStyle { + static func listPickerContentStyle(_ style: some ListPickerContentStyle) -> ListPickerDestinationListPickerContentStyle { + ListPickerDestinationListPickerContentStyle(style: style) + } + + static func listPickerContentStyle(@ViewBuilder content: @escaping (ListPickerContentConfiguration) -> some View) -> ListPickerDestinationListPickerContentStyle { + let style = AnyListPickerContentStyle(content) + return ListPickerDestinationListPickerContentStyle(style: style) + } +} + +// MARK: ListPickerItemStyle + +public extension ListPickerItemStyle where Self == ListPickerItemBaseStyle { + static var base: ListPickerItemBaseStyle { + ListPickerItemBaseStyle() + } +} + +public extension ListPickerItemStyle where Self == ListPickerItemFioriStyle { + static var fiori: ListPickerItemFioriStyle { + ListPickerItemFioriStyle() + } +} + +public struct ListPickerItemTitleStyle: ListPickerItemStyle { + let style: any TitleStyle + + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + ListPickerItem(configuration) + .titleStyle(self.style) + .typeErased + } +} + +public extension ListPickerItemStyle where Self == ListPickerItemTitleStyle { + static func titleStyle(_ style: some TitleStyle) -> ListPickerItemTitleStyle { + ListPickerItemTitleStyle(style: style) + } + + static func titleStyle(@ViewBuilder content: @escaping (TitleConfiguration) -> some View) -> ListPickerItemTitleStyle { + let style = AnyTitleStyle(content) + return ListPickerItemTitleStyle(style: style) + } +} + +public struct ListPickerItemValueStyle: ListPickerItemStyle { + let style: any ValueStyle + + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + ListPickerItem(configuration) + .valueStyle(self.style) + .typeErased + } +} + +public extension ListPickerItemStyle where Self == ListPickerItemValueStyle { + static func valueStyle(_ style: some ValueStyle) -> ListPickerItemValueStyle { + ListPickerItemValueStyle(style: style) + } + + static func valueStyle(@ViewBuilder content: @escaping (ValueConfiguration) -> some View) -> ListPickerItemValueStyle { + let style = AnyValueStyle(content) + return ListPickerItemValueStyle(style: style) + } +} + // MARK: MandatoryFieldIndicatorStyle public extension MandatoryFieldIndicatorStyle where Self == MandatoryFieldIndicatorBaseStyle { @@ -3741,6 +4028,34 @@ public extension SegmentedControlPickerStyle where Self == SegmentedControlPicke } } +// MARK: SelectAllActionStyle + +public extension SelectAllActionStyle where Self == SelectAllActionBaseStyle { + static var base: SelectAllActionBaseStyle { + SelectAllActionBaseStyle() + } +} + +public extension SelectAllActionStyle where Self == SelectAllActionFioriStyle { + static var fiori: SelectAllActionFioriStyle { + SelectAllActionFioriStyle() + } +} + +// MARK: SelectedEntriesSectionTitleStyle + +public extension SelectedEntriesSectionTitleStyle where Self == SelectedEntriesSectionTitleBaseStyle { + static var base: SelectedEntriesSectionTitleBaseStyle { + SelectedEntriesSectionTitleBaseStyle() + } +} + +public extension SelectedEntriesSectionTitleStyle where Self == SelectedEntriesSectionTitleFioriStyle { + static var fiori: SelectedEntriesSectionTitleFioriStyle { + SelectedEntriesSectionTitleFioriStyle() + } +} + // MARK: SideBarStyle public extension SideBarStyle where Self == SideBarBaseStyle { @@ -5239,6 +5554,20 @@ public extension TopDividerStyle where Self == TopDividerFioriStyle { } } +// MARK: ValueStyle + +public extension ValueStyle where Self == ValueBaseStyle { + static var base: ValueBaseStyle { + ValueBaseStyle() + } +} + +public extension ValueStyle where Self == ValueFioriStyle { + static var fiori: ValueFioriStyle { + ValueFioriStyle() + } +} + // MARK: ValueLabelStyle public extension ValueLabelStyle where Self == ValueLabelBaseStyle { diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/EnvironmentVariables.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/EnvironmentVariables.generated.swift index 7bb8863fc..322443c48 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/EnvironmentVariables.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/EnvironmentVariables.generated.swift @@ -45,6 +45,48 @@ extension EnvironmentValues { } } +// MARK: AllEntriesSectionTitleStyle + +struct AllEntriesSectionTitleStyleStackKey: EnvironmentKey { + static let defaultValue: [any AllEntriesSectionTitleStyle] = [] +} + +extension EnvironmentValues { + var allEntriesSectionTitleStyle: any AllEntriesSectionTitleStyle { + self.allEntriesSectionTitleStyleStack.last ?? .base + } + + var allEntriesSectionTitleStyleStack: [any AllEntriesSectionTitleStyle] { + get { + self[AllEntriesSectionTitleStyleStackKey.self] + } + set { + self[AllEntriesSectionTitleStyleStackKey.self] = newValue + } + } +} + +// MARK: ApplyActionStyle + +struct ApplyActionStyleStackKey: EnvironmentKey { + static let defaultValue: [any ApplyActionStyle] = [] +} + +extension EnvironmentValues { + var applyActionStyle: any ApplyActionStyle { + self.applyActionStyleStack.last ?? .base + } + + var applyActionStyleStack: [any ApplyActionStyle] { + get { + self[ApplyActionStyleStackKey.self] + } + set { + self[ApplyActionStyleStackKey.self] = newValue + } + } +} + // MARK: AttributeStyle struct AttributeStyleStackKey: EnvironmentKey { @@ -150,6 +192,27 @@ extension EnvironmentValues { } } +// MARK: CancelActionStyle + +struct CancelActionStyleStackKey: EnvironmentKey { + static let defaultValue: [any CancelActionStyle] = [] +} + +extension EnvironmentValues { + var cancelActionStyle: any CancelActionStyle { + self.cancelActionStyleStack.last ?? .base + } + + var cancelActionStyleStack: [any CancelActionStyle] { + get { + self[CancelActionStyleStackKey.self] + } + set { + self[CancelActionStyleStackKey.self] = newValue + } + } +} + // MARK: CardBodyStyle struct CardBodyStyleStackKey: EnvironmentKey { @@ -423,6 +486,27 @@ extension EnvironmentValues { } } +// MARK: DeselectAllActionStyle + +struct DeselectAllActionStyleStackKey: EnvironmentKey { + static let defaultValue: [any DeselectAllActionStyle] = [] +} + +extension EnvironmentValues { + var deselectAllActionStyle: any DeselectAllActionStyle { + self.deselectAllActionStyleStack.last ?? .base + } + + var deselectAllActionStyleStack: [any DeselectAllActionStyle] { + get { + self[DeselectAllActionStyleStackKey.self] + } + set { + self[DeselectAllActionStyleStackKey.self] = newValue + } + } +} + // MARK: DetailImageStyle struct DetailImageStyleStackKey: EnvironmentKey { @@ -885,6 +969,69 @@ extension EnvironmentValues { } } +// MARK: ListPickerContentStyle + +struct ListPickerContentStyleStackKey: EnvironmentKey { + static let defaultValue: [any ListPickerContentStyle] = [] +} + +extension EnvironmentValues { + var listPickerContentStyle: any ListPickerContentStyle { + self.listPickerContentStyleStack.last ?? .base + } + + var listPickerContentStyleStack: [any ListPickerContentStyle] { + get { + self[ListPickerContentStyleStackKey.self] + } + set { + self[ListPickerContentStyleStackKey.self] = newValue + } + } +} + +// MARK: ListPickerDestinationStyle + +struct ListPickerDestinationStyleStackKey: EnvironmentKey { + static let defaultValue: [any ListPickerDestinationStyle] = [] +} + +extension EnvironmentValues { + var listPickerDestinationStyle: any ListPickerDestinationStyle { + self.listPickerDestinationStyleStack.last ?? .base.concat(.fiori) + } + + var listPickerDestinationStyleStack: [any ListPickerDestinationStyle] { + get { + self[ListPickerDestinationStyleStackKey.self] + } + set { + self[ListPickerDestinationStyleStackKey.self] = newValue + } + } +} + +// MARK: ListPickerItemStyle + +struct ListPickerItemStyleStackKey: EnvironmentKey { + static let defaultValue: [any ListPickerItemStyle] = [] +} + +extension EnvironmentValues { + var listPickerItemStyle: any ListPickerItemStyle { + self.listPickerItemStyleStack.last ?? .base.concat(.fiori) + } + + var listPickerItemStyleStack: [any ListPickerItemStyle] { + get { + self[ListPickerItemStyleStackKey.self] + } + set { + self[ListPickerItemStyleStackKey.self] = newValue + } + } +} + // MARK: MandatoryFieldIndicatorStyle struct MandatoryFieldIndicatorStyleStackKey: EnvironmentKey { @@ -1452,6 +1599,48 @@ extension EnvironmentValues { } } +// MARK: SelectAllActionStyle + +struct SelectAllActionStyleStackKey: EnvironmentKey { + static let defaultValue: [any SelectAllActionStyle] = [] +} + +extension EnvironmentValues { + var selectAllActionStyle: any SelectAllActionStyle { + self.selectAllActionStyleStack.last ?? .base + } + + var selectAllActionStyleStack: [any SelectAllActionStyle] { + get { + self[SelectAllActionStyleStackKey.self] + } + set { + self[SelectAllActionStyleStackKey.self] = newValue + } + } +} + +// MARK: SelectedEntriesSectionTitleStyle + +struct SelectedEntriesSectionTitleStyleStackKey: EnvironmentKey { + static let defaultValue: [any SelectedEntriesSectionTitleStyle] = [] +} + +extension EnvironmentValues { + var selectedEntriesSectionTitleStyle: any SelectedEntriesSectionTitleStyle { + self.selectedEntriesSectionTitleStyleStack.last ?? .base + } + + var selectedEntriesSectionTitleStyleStack: [any SelectedEntriesSectionTitleStyle] { + get { + self[SelectedEntriesSectionTitleStyleStackKey.self] + } + set { + self[SelectedEntriesSectionTitleStyleStackKey.self] = newValue + } + } +} + // MARK: SideBarStyle struct SideBarStyleStackKey: EnvironmentKey { @@ -1998,6 +2187,27 @@ extension EnvironmentValues { } } +// MARK: ValueStyle + +struct ValueStyleStackKey: EnvironmentKey { + static let defaultValue: [any ValueStyle] = [] +} + +extension EnvironmentValues { + var valueStyle: any ValueStyle { + self.valueStyleStack.last ?? .base + } + + var valueStyleStack: [any ValueStyle] { + get { + self[ValueStyleStackKey.self] + } + set { + self[ValueStyleStackKey.self] = newValue + } + } +} + // MARK: ValueLabelStyle struct ValueLabelStyleStackKey: EnvironmentKey { diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ModifiedStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ModifiedStyle.generated.swift index 5edc2b190..d20b7d7f6 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ModifiedStyle.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ModifiedStyle.generated.swift @@ -64,6 +64,62 @@ public extension ActionStyle { } } +// MARK: AllEntriesSectionTitleStyle + +extension ModifiedStyle: AllEntriesSectionTitleStyle where Style: AllEntriesSectionTitleStyle { + public func makeBody(_ configuration: AllEntriesSectionTitleConfiguration) -> some View { + AllEntriesSectionTitle(configuration) + .allEntriesSectionTitleStyle(self.style) + .modifier(self.modifier) + } +} + +public struct AllEntriesSectionTitleStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.allEntriesSectionTitleStyle(self.style) + } +} + +public extension AllEntriesSectionTitleStyle { + func modifier(_ modifier: some ViewModifier) -> some AllEntriesSectionTitleStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some AllEntriesSectionTitleStyle) -> some AllEntriesSectionTitleStyle { + style.modifier(AllEntriesSectionTitleStyleModifier(style: self)) + } +} + +// MARK: ApplyActionStyle + +extension ModifiedStyle: ApplyActionStyle where Style: ApplyActionStyle { + public func makeBody(_ configuration: ApplyActionConfiguration) -> some View { + ApplyAction(configuration) + .applyActionStyle(self.style) + .modifier(self.modifier) + } +} + +public struct ApplyActionStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.applyActionStyle(self.style) + } +} + +public extension ApplyActionStyle { + func modifier(_ modifier: some ViewModifier) -> some ApplyActionStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some ApplyActionStyle) -> some ApplyActionStyle { + style.modifier(ApplyActionStyleModifier(style: self)) + } +} + // MARK: AttributeStyle extension ModifiedStyle: AttributeStyle where Style: AttributeStyle { @@ -204,6 +260,34 @@ public extension BannerMessageStyle { } } +// MARK: CancelActionStyle + +extension ModifiedStyle: CancelActionStyle where Style: CancelActionStyle { + public func makeBody(_ configuration: CancelActionConfiguration) -> some View { + CancelAction(configuration) + .cancelActionStyle(self.style) + .modifier(self.modifier) + } +} + +public struct CancelActionStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.cancelActionStyle(self.style) + } +} + +public extension CancelActionStyle { + func modifier(_ modifier: some ViewModifier) -> some CancelActionStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some CancelActionStyle) -> some CancelActionStyle { + style.modifier(CancelActionStyleModifier(style: self)) + } +} + // MARK: CardBodyStyle extension ModifiedStyle: CardBodyStyle where Style: CardBodyStyle { @@ -568,6 +652,34 @@ public extension DescriptionStyle { } } +// MARK: DeselectAllActionStyle + +extension ModifiedStyle: DeselectAllActionStyle where Style: DeselectAllActionStyle { + public func makeBody(_ configuration: DeselectAllActionConfiguration) -> some View { + DeselectAllAction(configuration) + .deselectAllActionStyle(self.style) + .modifier(self.modifier) + } +} + +public struct DeselectAllActionStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.deselectAllActionStyle(self.style) + } +} + +public extension DeselectAllActionStyle { + func modifier(_ modifier: some ViewModifier) -> some DeselectAllActionStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some DeselectAllActionStyle) -> some DeselectAllActionStyle { + style.modifier(DeselectAllActionStyleModifier(style: self)) + } +} + // MARK: DetailImageStyle extension ModifiedStyle: DetailImageStyle where Style: DetailImageStyle { @@ -1184,6 +1296,90 @@ public extension LinearProgressIndicatorViewStyle { } } +// MARK: ListPickerContentStyle + +extension ModifiedStyle: ListPickerContentStyle where Style: ListPickerContentStyle { + public func makeBody(_ configuration: ListPickerContentConfiguration) -> some View { + ListPickerContent(configuration) + .listPickerContentStyle(self.style) + .modifier(self.modifier) + } +} + +public struct ListPickerContentStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.listPickerContentStyle(self.style) + } +} + +public extension ListPickerContentStyle { + func modifier(_ modifier: some ViewModifier) -> some ListPickerContentStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some ListPickerContentStyle) -> some ListPickerContentStyle { + style.modifier(ListPickerContentStyleModifier(style: self)) + } +} + +// MARK: ListPickerDestinationStyle + +extension ModifiedStyle: ListPickerDestinationStyle where Style: ListPickerDestinationStyle { + public func makeBody(_ configuration: ListPickerDestinationConfiguration) -> some View { + ListPickerDestination(configuration) + .listPickerDestinationStyle(self.style) + .modifier(self.modifier) + } +} + +public struct ListPickerDestinationStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.listPickerDestinationStyle(self.style) + } +} + +public extension ListPickerDestinationStyle { + func modifier(_ modifier: some ViewModifier) -> some ListPickerDestinationStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some ListPickerDestinationStyle) -> some ListPickerDestinationStyle { + style.modifier(ListPickerDestinationStyleModifier(style: self)) + } +} + +// MARK: ListPickerItemStyle + +extension ModifiedStyle: ListPickerItemStyle where Style: ListPickerItemStyle { + public func makeBody(_ configuration: ListPickerItemConfiguration) -> some View { + ListPickerItem(configuration) + .listPickerItemStyle(self.style) + .modifier(self.modifier) + } +} + +public struct ListPickerItemStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.listPickerItemStyle(self.style) + } +} + +public extension ListPickerItemStyle { + func modifier(_ modifier: some ViewModifier) -> some ListPickerItemStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some ListPickerItemStyle) -> some ListPickerItemStyle { + style.modifier(ListPickerItemStyleModifier(style: self)) + } +} + // MARK: MandatoryFieldIndicatorStyle extension ModifiedStyle: MandatoryFieldIndicatorStyle where Style: MandatoryFieldIndicatorStyle { @@ -1940,6 +2136,62 @@ public extension SegmentedControlPickerStyle { } } +// MARK: SelectAllActionStyle + +extension ModifiedStyle: SelectAllActionStyle where Style: SelectAllActionStyle { + public func makeBody(_ configuration: SelectAllActionConfiguration) -> some View { + SelectAllAction(configuration) + .selectAllActionStyle(self.style) + .modifier(self.modifier) + } +} + +public struct SelectAllActionStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.selectAllActionStyle(self.style) + } +} + +public extension SelectAllActionStyle { + func modifier(_ modifier: some ViewModifier) -> some SelectAllActionStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some SelectAllActionStyle) -> some SelectAllActionStyle { + style.modifier(SelectAllActionStyleModifier(style: self)) + } +} + +// MARK: SelectedEntriesSectionTitleStyle + +extension ModifiedStyle: SelectedEntriesSectionTitleStyle where Style: SelectedEntriesSectionTitleStyle { + public func makeBody(_ configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + SelectedEntriesSectionTitle(configuration) + .selectedEntriesSectionTitleStyle(self.style) + .modifier(self.modifier) + } +} + +public struct SelectedEntriesSectionTitleStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.selectedEntriesSectionTitleStyle(self.style) + } +} + +public extension SelectedEntriesSectionTitleStyle { + func modifier(_ modifier: some ViewModifier) -> some SelectedEntriesSectionTitleStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some SelectedEntriesSectionTitleStyle) -> some SelectedEntriesSectionTitleStyle { + style.modifier(SelectedEntriesSectionTitleStyleModifier(style: self)) + } +} + // MARK: SideBarStyle extension ModifiedStyle: SideBarStyle where Style: SideBarStyle { @@ -2668,6 +2920,34 @@ public extension TopDividerStyle { } } +// MARK: ValueStyle + +extension ModifiedStyle: ValueStyle where Style: ValueStyle { + public func makeBody(_ configuration: ValueConfiguration) -> some View { + Value(configuration) + .valueStyle(self.style) + .modifier(self.modifier) + } +} + +public struct ValueStyleModifier: ViewModifier { + let style: Style + + public func body(content: Content) -> some View { + content.valueStyle(self.style) + } +} + +public extension ValueStyle { + func modifier(_ modifier: some ViewModifier) -> some ValueStyle { + ModifiedStyle(style: self, modifier: modifier) + } + + func concat(_ style: some ValueStyle) -> some ValueStyle { + style.modifier(ValueStyleModifier(style: self)) + } +} + // MARK: ValueLabelStyle extension ModifiedStyle: ValueLabelStyle where Style: ValueLabelStyle { diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ResolvedStyle.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ResolvedStyle.generated.swift index 1ef7477ee..a73079c9c 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ResolvedStyle.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ResolvedStyle.generated.swift @@ -35,6 +35,38 @@ extension ActionStyle { } } +// MARK: AllEntriesSectionTitleStyle + +struct ResolvedAllEntriesSectionTitleStyle: View { + let style: Style + let configuration: AllEntriesSectionTitleConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension AllEntriesSectionTitleStyle { + func resolve(configuration: AllEntriesSectionTitleConfiguration) -> some View { + ResolvedAllEntriesSectionTitleStyle(style: self, configuration: configuration) + } +} + +// MARK: ApplyActionStyle + +struct ResolvedApplyActionStyle: View { + let style: Style + let configuration: ApplyActionConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension ApplyActionStyle { + func resolve(configuration: ApplyActionConfiguration) -> some View { + ResolvedApplyActionStyle(style: self, configuration: configuration) + } +} + // MARK: AttributeStyle struct ResolvedAttributeStyle: View { @@ -115,6 +147,22 @@ extension BannerMessageStyle { } } +// MARK: CancelActionStyle + +struct ResolvedCancelActionStyle: View { + let style: Style + let configuration: CancelActionConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension CancelActionStyle { + func resolve(configuration: CancelActionConfiguration) -> some View { + ResolvedCancelActionStyle(style: self, configuration: configuration) + } +} + // MARK: CardBodyStyle struct ResolvedCardBodyStyle: View { @@ -323,6 +371,22 @@ extension DescriptionStyle { } } +// MARK: DeselectAllActionStyle + +struct ResolvedDeselectAllActionStyle: View { + let style: Style + let configuration: DeselectAllActionConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension DeselectAllActionStyle { + func resolve(configuration: DeselectAllActionConfiguration) -> some View { + ResolvedDeselectAllActionStyle(style: self, configuration: configuration) + } +} + // MARK: DetailImageStyle struct ResolvedDetailImageStyle: View { @@ -675,6 +739,54 @@ extension LinearProgressIndicatorViewStyle { } } +// MARK: ListPickerContentStyle + +struct ResolvedListPickerContentStyle: View { + let style: Style + let configuration: ListPickerContentConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension ListPickerContentStyle { + func resolve(configuration: ListPickerContentConfiguration) -> some View { + ResolvedListPickerContentStyle(style: self, configuration: configuration) + } +} + +// MARK: ListPickerDestinationStyle + +struct ResolvedListPickerDestinationStyle: View { + let style: Style + let configuration: ListPickerDestinationConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension ListPickerDestinationStyle { + func resolve(configuration: ListPickerDestinationConfiguration) -> some View { + ResolvedListPickerDestinationStyle(style: self, configuration: configuration) + } +} + +// MARK: ListPickerItemStyle + +struct ResolvedListPickerItemStyle: View { + let style: Style + let configuration: ListPickerItemConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension ListPickerItemStyle { + func resolve(configuration: ListPickerItemConfiguration) -> some View { + ResolvedListPickerItemStyle(style: self, configuration: configuration) + } +} + // MARK: MandatoryFieldIndicatorStyle struct ResolvedMandatoryFieldIndicatorStyle: View { @@ -1107,6 +1219,38 @@ extension SegmentedControlPickerStyle { } } +// MARK: SelectAllActionStyle + +struct ResolvedSelectAllActionStyle: View { + let style: Style + let configuration: SelectAllActionConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension SelectAllActionStyle { + func resolve(configuration: SelectAllActionConfiguration) -> some View { + ResolvedSelectAllActionStyle(style: self, configuration: configuration) + } +} + +// MARK: SelectedEntriesSectionTitleStyle + +struct ResolvedSelectedEntriesSectionTitleStyle: View { + let style: Style + let configuration: SelectedEntriesSectionTitleConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension SelectedEntriesSectionTitleStyle { + func resolve(configuration: SelectedEntriesSectionTitleConfiguration) -> some View { + ResolvedSelectedEntriesSectionTitleStyle(style: self, configuration: configuration) + } +} + // MARK: SideBarStyle struct ResolvedSideBarStyle: View { @@ -1523,6 +1667,22 @@ extension TopDividerStyle { } } +// MARK: ValueStyle + +struct ResolvedValueStyle: View { + let style: Style + let configuration: ValueConfiguration + var body: some View { + self.style.makeBody(self.configuration) + } +} + +extension ValueStyle { + func resolve(configuration: ValueConfiguration) -> some View { + ResolvedValueStyle(style: self, configuration: configuration) + } +} + // MARK: ValueLabelStyle struct ResolvedValueLabelStyle: View { diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/View+Extension_.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/View+Extension_.generated.swift index 113ecfd45..24284ee49 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/View+Extension_.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/View+Extension_.generated.swift @@ -37,6 +37,40 @@ public extension View { } } +// MARK: AllEntriesSectionTitleStyle + +public extension View { + func allEntriesSectionTitleStyle(_ style: some AllEntriesSectionTitleStyle) -> some View { + self.transformEnvironment(\.allEntriesSectionTitleStyleStack) { stack in + stack.append(style) + } + } + + func allEntriesSectionTitleStyle(@ViewBuilder content: @escaping (AllEntriesSectionTitleConfiguration) -> some View) -> some View { + self.transformEnvironment(\.allEntriesSectionTitleStyleStack) { stack in + let style = AnyAllEntriesSectionTitleStyle(content) + stack.append(style) + } + } +} + +// MARK: ApplyActionStyle + +public extension View { + func applyActionStyle(_ style: some ApplyActionStyle) -> some View { + self.transformEnvironment(\.applyActionStyleStack) { stack in + stack.append(style) + } + } + + func applyActionStyle(@ViewBuilder content: @escaping (ApplyActionConfiguration) -> some View) -> some View { + self.transformEnvironment(\.applyActionStyleStack) { stack in + let style = AnyApplyActionStyle(content) + stack.append(style) + } + } +} + // MARK: AttributeStyle public extension View { @@ -122,6 +156,23 @@ public extension View { } } +// MARK: CancelActionStyle + +public extension View { + func cancelActionStyle(_ style: some CancelActionStyle) -> some View { + self.transformEnvironment(\.cancelActionStyleStack) { stack in + stack.append(style) + } + } + + func cancelActionStyle(@ViewBuilder content: @escaping (CancelActionConfiguration) -> some View) -> some View { + self.transformEnvironment(\.cancelActionStyleStack) { stack in + let style = AnyCancelActionStyle(content) + stack.append(style) + } + } +} + // MARK: CardBodyStyle public extension View { @@ -343,6 +394,23 @@ public extension View { } } +// MARK: DeselectAllActionStyle + +public extension View { + func deselectAllActionStyle(_ style: some DeselectAllActionStyle) -> some View { + self.transformEnvironment(\.deselectAllActionStyleStack) { stack in + stack.append(style) + } + } + + func deselectAllActionStyle(@ViewBuilder content: @escaping (DeselectAllActionConfiguration) -> some View) -> some View { + self.transformEnvironment(\.deselectAllActionStyleStack) { stack in + let style = AnyDeselectAllActionStyle(content) + stack.append(style) + } + } +} + // MARK: DetailImageStyle public extension View { @@ -717,6 +785,57 @@ public extension View { } } +// MARK: ListPickerContentStyle + +public extension View { + func listPickerContentStyle(_ style: some ListPickerContentStyle) -> some View { + self.transformEnvironment(\.listPickerContentStyleStack) { stack in + stack.append(style) + } + } + + func listPickerContentStyle(@ViewBuilder content: @escaping (ListPickerContentConfiguration) -> some View) -> some View { + self.transformEnvironment(\.listPickerContentStyleStack) { stack in + let style = AnyListPickerContentStyle(content) + stack.append(style) + } + } +} + +// MARK: ListPickerDestinationStyle + +public extension View { + func listPickerDestinationStyle(_ style: some ListPickerDestinationStyle) -> some View { + self.transformEnvironment(\.listPickerDestinationStyleStack) { stack in + stack.append(style) + } + } + + func listPickerDestinationStyle(@ViewBuilder content: @escaping (ListPickerDestinationConfiguration) -> some View) -> some View { + self.transformEnvironment(\.listPickerDestinationStyleStack) { stack in + let style = AnyListPickerDestinationStyle(content) + stack.append(style) + } + } +} + +// MARK: ListPickerItemStyle + +public extension View { + func listPickerItemStyle(_ style: some ListPickerItemStyle) -> some View { + self.transformEnvironment(\.listPickerItemStyleStack) { stack in + stack.append(style) + } + } + + func listPickerItemStyle(@ViewBuilder content: @escaping (ListPickerItemConfiguration) -> some View) -> some View { + self.transformEnvironment(\.listPickerItemStyleStack) { stack in + let style = AnyListPickerItemStyle(content) + stack.append(style) + } + } +} + // MARK: MandatoryFieldIndicatorStyle public extension View { @@ -1176,6 +1295,40 @@ public extension View { } } +// MARK: SelectAllActionStyle + +public extension View { + func selectAllActionStyle(_ style: some SelectAllActionStyle) -> some View { + self.transformEnvironment(\.selectAllActionStyleStack) { stack in + stack.append(style) + } + } + + func selectAllActionStyle(@ViewBuilder content: @escaping (SelectAllActionConfiguration) -> some View) -> some View { + self.transformEnvironment(\.selectAllActionStyleStack) { stack in + let style = AnySelectAllActionStyle(content) + stack.append(style) + } + } +} + +// MARK: SelectedEntriesSectionTitleStyle + +public extension View { + func selectedEntriesSectionTitleStyle(_ style: some SelectedEntriesSectionTitleStyle) -> some View { + self.transformEnvironment(\.selectedEntriesSectionTitleStyleStack) { stack in + stack.append(style) + } + } + + func selectedEntriesSectionTitleStyle(@ViewBuilder content: @escaping (SelectedEntriesSectionTitleConfiguration) -> some View) -> some View { + self.transformEnvironment(\.selectedEntriesSectionTitleStyleStack) { stack in + let style = AnySelectedEntriesSectionTitleStyle(content) + stack.append(style) + } + } +} + // MARK: SideBarStyle public extension View { @@ -1618,6 +1771,23 @@ public extension View { } } +// MARK: ValueStyle + +public extension View { + func valueStyle(_ style: some ValueStyle) -> some View { + self.transformEnvironment(\.valueStyleStack) { stack in + stack.append(style) + } + } + + func valueStyle(@ViewBuilder content: @escaping (ValueConfiguration) -> some View) -> some View { + self.transformEnvironment(\.valueStyleStack) { stack in + let style = AnyValueStyle(content) + stack.append(style) + } + } +} + // MARK: ValueLabelStyle public extension View { diff --git a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ViewEmptyChecking+Extension.generated.swift b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ViewEmptyChecking+Extension.generated.swift index 26992172d..e1f93e8c1 100755 --- a/Sources/FioriSwiftUICore/_generated/SupportingFiles/ViewEmptyChecking+Extension.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/SupportingFiles/ViewEmptyChecking+Extension.generated.swift @@ -15,6 +15,18 @@ extension Action: _ViewEmptyChecking { } } +extension AllEntriesSectionTitle: _ViewEmptyChecking { + public var isEmpty: Bool { + allEntriesSectionTitle.isEmpty + } +} + +extension ApplyAction: _ViewEmptyChecking { + public var isEmpty: Bool { + applyAction.isEmpty + } +} + extension Attribute: _ViewEmptyChecking { public var isEmpty: Bool { attribute.isEmpty @@ -49,6 +61,12 @@ extension BannerMessage: _ViewEmptyChecking { } } +extension CancelAction: _ViewEmptyChecking { + public var isEmpty: Bool { + cancelAction.isEmpty + } +} + extension CardBody: _ViewEmptyChecking { public var isEmpty: Bool { cardBody.isEmpty @@ -174,6 +192,12 @@ extension Description: _ViewEmptyChecking { } } +extension DeselectAllAction: _ViewEmptyChecking { + public var isEmpty: Bool { + deselectAllAction.isEmpty + } +} + extension DetailImage: _ViewEmptyChecking { public var isEmpty: Bool { detailImage.isEmpty @@ -319,6 +343,32 @@ extension LinearProgressIndicatorView: _ViewEmptyChecking { } } +extension ListPickerContent: _ViewEmptyChecking { + public var isEmpty: Bool { + listPickerContent.isEmpty + } +} + +extension ListPickerDestination: _ViewEmptyChecking { + public var isEmpty: Bool { + cancelAction.isEmpty && + applyAction.isEmpty && + selectedEntriesSectionTitle.isEmpty && + selectAllAction.isEmpty && + deselectAllAction.isEmpty && + allEntriesSectionTitle.isEmpty && + listPickerContent.isEmpty + } +} + +extension ListPickerItem: _ViewEmptyChecking { + public var isEmpty: Bool { + title.isEmpty && + value.isEmpty && + destination.isEmpty + } +} + extension MandatoryFieldIndicator: _ViewEmptyChecking { public var isEmpty: Bool { mandatoryFieldIndicator.isEmpty @@ -509,6 +559,18 @@ extension SegmentedControlPicker: _ViewEmptyChecking { } } +extension SelectAllAction: _ViewEmptyChecking { + public var isEmpty: Bool { + selectAllAction.isEmpty + } +} + +extension SelectedEntriesSectionTitle: _ViewEmptyChecking { + public var isEmpty: Bool { + selectedEntriesSectionTitle.isEmpty + } +} + extension SideBar: _ViewEmptyChecking { public var isEmpty: Bool { footer.isEmpty && @@ -696,6 +758,12 @@ extension TopDivider: _ViewEmptyChecking { } } +extension Value: _ViewEmptyChecking { + public var isEmpty: Bool { + value.isEmpty + } +} + extension ValueLabel: _ViewEmptyChecking { public var isEmpty: Bool { valueLabel.isEmpty diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/API/ListPickerItem+API.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/API/_ListPickerItem+API.generated.swift similarity index 68% rename from Sources/FioriSwiftUICore/_generated/ViewModels/API/ListPickerItem+API.generated.swift rename to Sources/FioriSwiftUICore/_generated/ViewModels/API/_ListPickerItem+API.generated.swift index 73acaaae9..90781b45a 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/API/ListPickerItem+API.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/API/_ListPickerItem+API.generated.swift @@ -2,7 +2,7 @@ // DO NOT EDIT import SwiftUI -public struct ListPickerItem { +public struct _ListPickerItem { @Environment(\.keyModifier) private var keyModifier @Environment(\.valueModifier) private var valueModifier @Environment(\.listPickerListViewModifier) var listPickerListViewModifier @@ -12,7 +12,8 @@ public struct ListPickerItem { let _key: Key let _value: Value let _axis: Axis - var destinationConfiguration: ListPickerItemConfiguration? = nil + var destinationConfiguration: _ListPickerItemConfiguration? = nil + private var isModelInit: Bool = false private var isValueNil: Bool = false @@ -28,16 +29,16 @@ public struct ListPickerItem { @ViewBuilder var key: some View { if isModelInit { - _key.modifier(keyModifier.concat(Fiori.ListPickerItem.key).concat(Fiori.ListPickerItem.keyCumulative)) + _key.modifier(keyModifier.concat(Fiori._ListPickerItem.key).concat(Fiori._ListPickerItem.keyCumulative)) } else { - _key.modifier(keyModifier.concat(Fiori.ListPickerItem.key)) + _key.modifier(keyModifier.concat(Fiori._ListPickerItem.key)) } } @ViewBuilder var value: some View { if isModelInit { - _value.modifier(valueModifier.concat(Fiori.ListPickerItem.value).concat(Fiori.ListPickerItem.valueCumulative)) + _value.modifier(valueModifier.concat(Fiori._ListPickerItem.value).concat(Fiori._ListPickerItem.valueCumulative)) } else { - _value.modifier(valueModifier.concat(Fiori.ListPickerItem.value)) + _value.modifier(valueModifier.concat(Fiori._ListPickerItem.value)) } } @@ -46,11 +47,11 @@ public struct ListPickerItem { } } -extension ListPickerItem where Key == Text, +extension _ListPickerItem where Key == Text, Value == _ConditionalContent { - public init(model: ListPickerItemModel) { - self.init(key: model.key, value: model.value, axis: model.axis) + public init(model: _ListPickerItemModel) { + self.init(key: model.key, value: model.value) } public init(key: String, value: String? = nil, axis: Axis = .horizontal) { diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/ListPickerItem+View.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/_ListPickerItem+View.generated.swift similarity index 80% rename from Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/ListPickerItem+View.generated.swift rename to Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/_ListPickerItem+View.generated.swift index 1ef7da4ed..43d637a15 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/ListPickerItem+View.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/Boilerplate/_ListPickerItem+View.generated.swift @@ -1,8 +1,8 @@ // Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery // DO NOT EDIT -//TODO: Copy commented code to new file: `FioriSwiftUICore/Views/ListPickerItem+View.swift` +//TODO: Copy commented code to new file: `FioriSwiftUICore/Views/_ListPickerItem+View.swift` //TODO: Implement default Fiori style definitions as `ViewModifier` -//TODO: Implement ListPickerItem `View` body +//TODO: Implement _ListPickerItem `View` body //TODO: Implement LibraryContentProvider /// - Important: to make `@Environment` properties (e.g. `horizontalSizeClass`), internally accessible @@ -16,7 +16,7 @@ import SwiftUI // FIXME: - Implement Fiori style definitions extension Fiori { - enum ListPickerItem { + enum _ListPickerItem { typealias Key = EmptyModifier typealias KeyCumulative = EmptyModifier typealias Value = EmptyModifier @@ -41,21 +41,21 @@ extension Fiori { } } -// FIXME: - Implement ListPickerItem View body +// FIXME: - Implement _ListPickerItem View body -extension ListPickerItem: View { +extension _ListPickerItem: View { public var body: some View { <# View body #> } } -// FIXME: - Implement ListPickerItem specific LibraryContentProvider +// FIXME: - Implement _ListPickerItem specific LibraryContentProvider @available(iOS 14.0, macOS 11.0, *) -struct ListPickerItemLibraryContent: LibraryContentProvider { +struct _ListPickerItemLibraryContent: LibraryContentProvider { @LibraryContentBuilder var views: [LibraryItem] { - LibraryItem(ListPickerItem(model: LibraryPreviewData.Person.laurelosborn), + LibraryItem(_ListPickerItem(model: LibraryPreviewData.Person.laurelosborn), category: .control) } } diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/ListPickerItem+Init.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/_ListPickerItem+Init.generated.swift similarity index 84% rename from Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/ListPickerItem+Init.generated.swift rename to Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/_ListPickerItem+Init.generated.swift index dda81d83a..e99d2043a 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/ListPickerItem+Init.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/Init+Extensions/_ListPickerItem+Init.generated.swift @@ -2,7 +2,7 @@ // DO NOT EDIT import SwiftUI -extension ListPickerItem where Value == EmptyView { +extension _ListPickerItem where Value == EmptyView { public init( @ViewBuilder key: () -> Key, axis: Axis = .horizontal diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/ListPickerItemModel+Extensions.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/_ListPickerItemModel+Extensions.generated.swift similarity index 81% rename from Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/ListPickerItemModel+Extensions.generated.swift rename to Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/_ListPickerItemModel+Extensions.generated.swift index 5d472868a..f48fb6d4f 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/ListPickerItemModel+Extensions.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/Model+Extensions/_ListPickerItemModel+Extensions.generated.swift @@ -2,7 +2,7 @@ // DO NOT EDIT import SwiftUI -public extension ListPickerItemModel { +public extension _ListPickerItemModel { var axis: Axis { return .horizontal } diff --git a/Sources/FioriSwiftUICore/_localization/en.lproj/FioriSwiftUICore.strings b/Sources/FioriSwiftUICore/_localization/en.lproj/FioriSwiftUICore.strings index 8424bd53b..013c7856c 100644 --- a/Sources/FioriSwiftUICore/_localization/en.lproj/FioriSwiftUICore.strings +++ b/Sources/FioriSwiftUICore/_localization/en.lproj/FioriSwiftUICore.strings @@ -253,3 +253,12 @@ "warnings" = "warnings"; /* XBUT: banner message type desc in plural form, errors */ "errors" = "errors"; + +/* XBUT: Title for apply action in trailing navigation bar */ +"Apply" = "Apply" +/* XTIT: The alert message for `ListPickerDestination` pulldown dismissal */ +"Are you sure you want to discard your selections?" = "Are you sure you want to discard your selections?"; +/* XBUT: The alert Discard Changes action title for `ListPickerDestination` pulldown dismissal */ +"Discard Changes" = "Discard Changes"; +/* XBUT: The alert Keep Editing action title for `ListPickerDestination` pulldown dismissal */ +"Keep Editing" = "Keep Editing"; diff --git a/sourcery/.lib/Sources/utils/Type+Extensions.swift b/sourcery/.lib/Sources/utils/Type+Extensions.swift index 504fc1542..87520f86d 100644 --- a/sourcery/.lib/Sources/utils/Type+Extensions.swift +++ b/sourcery/.lib/Sources/utils/Type+Extensions.swift @@ -68,8 +68,13 @@ extension Type { public extension Type { var componentName: String { var name = name + let deprecatedComponents = ["_ListPickerItemModel", + "_ActionModel", + "_ObjectItemModel", + "_SideBarModel", + "_SideBarListItemModel"] - if name == "_ActionModel" || name == "_ObjectItemModel" || name == "_SideBarModel" || name == "_SideBarListItemModel"{ + if deprecatedComponents.contains(name) { return name.replacingOccurrences(of: "Model", with: "") }