@@ -42,68 +42,103 @@ public struct PickerMenu: View {
4242 self . items = items
4343 self . titleText = titleText
4444 self . router = router
45- if let selectedItem {
46- self . _selectedItem = State ( initialValue: selectedItem)
47- }
45+ self . _selectedItem = State ( initialValue: selectedItem ?? items. first ?? PickerItem ( key: " " , value: " " ) )
4846 self . selected = selected
4947 }
50-
48+
49+ private var filteredItems : [ PickerItem ] {
50+ if search. isEmpty {
51+ return items
52+ } else {
53+ return items. filter { $0. value. localizedCaseInsensitiveContains ( search) }
54+ }
55+ }
56+
57+ private var isSingleSelection : Bool {
58+ return filteredItems. count == 1
59+ }
60+
61+ private var isItemSelected : Bool {
62+ return filteredItems. contains ( selectedItem)
63+ }
64+
65+ private var acceptButtonDisabled : Bool {
66+ return !isItemSelected && !isSingleSelection
67+ }
68+
5169 public var body : some View {
5270 VStack {
5371 ZStack ( alignment: . bottom) {
54- Color . black. opacity ( 0.4 )
55- . onTapGesture ( perform: {
56- router. dismiss ( animated: true )
57- } )
72+ Color . black. opacity ( 0.4 )
73+ . ignoresSafeArea ( )
74+ . onTapGesture {
75+ router. dismiss ( animated: true )
76+ }
77+ VStack {
78+ Spacer ( )
5879 VStack {
59- VStack {
60- Text ( titleText)
61- . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
62- TextField ( CoreLocalization . Picker. search, text: $search)
63- . padding ( . all, 8 )
64- . background (
65- CoreAssets . textInputStroke. swiftUIColor
66- . cornerRadius ( 6 ) )
67- Picker ( " " , selection: $selectedItem) {
68- let filteredItems = items
69- . filter ( { $0. value. contains ( search) } )
70- ForEach ( filteredItems. count != 0 ? filteredItems : items,
71- id: \. self) {
72- Text ( $0. value)
73- . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
74- }
75- } . pickerStyle ( . wheel)
76-
77- } . frame ( minWidth: 0 , maxWidth: idiom == . pad ? ipadPickerWidth : . infinity)
78- . padding ( )
79- . background (
80- CoreAssets . textInputBackground. swiftUIColor
81- . cornerRadius ( 16 )
82- ) . padding ( . horizontal, 16 )
83-
84- Button ( action: {
85- if items
86- . filter ( { $0. value. contains ( search) } ) . count == 1 {
87- selectedItem = items
88- . filter ( { $0. value. contains ( search) } ) [ 0 ]
80+ Text ( titleText)
81+ . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
82+ TextField ( CoreLocalization . Picker. search, text: $search)
83+ . padding ( . all, 8 )
84+ . background ( CoreAssets . textInputStroke. swiftUIColor. cornerRadius ( 6 ) )
85+ Picker ( " " , selection: $selectedItem) {
86+ ForEach ( filteredItems, id: \. self) { item in
87+ Text ( item. value)
88+ . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
8989 }
90- selected ( selectedItem)
91- router. dismiss ( animated: true )
92- } , label: {
93- Text ( CoreLocalization . Picker. accept)
94- . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
95- . frame ( minWidth: 0 , maxWidth: idiom == . pad ? ipadPickerWidth : . infinity)
96- . padding ( )
97- . background (
98- CoreAssets . textInputBackground. swiftUIColor
99- . cornerRadius ( 16 )
100- ) . padding ( . horizontal, 16 )
101- } )
102- . padding ( . bottom, 50 )
103-
104- } . transition ( . move( edge: . bottom) )
90+ }
91+ . pickerStyle ( . wheel)
92+ }
93+ . frame ( minWidth: 0 , maxWidth: idiom == . pad ? ipadPickerWidth : . infinity)
94+ . padding ( )
95+ . background ( CoreAssets . textInputBackground. swiftUIColor. cornerRadius ( 16 ) )
96+ . padding ( . horizontal, 16 )
97+ . onChange ( of: search, perform: { _ in
98+ if let first = filteredItems. first {
99+ self . selectedItem = first
100+ }
101+ } )
102+
103+ Button ( action: {
104+ selected ( selectedItem)
105+ router. dismiss ( animated: true )
106+ } ) {
107+ Text ( CoreLocalization . Picker. accept)
108+ . foregroundColor ( CoreAssets . textPrimary. swiftUIColor)
109+ . frame ( minWidth: 0 , maxWidth: idiom == . pad ? ipadPickerWidth : . infinity)
110+ . padding ( )
111+ . background ( CoreAssets . textInputBackground. swiftUIColor. cornerRadius ( 16 ) )
112+ . padding ( . horizontal, 16 )
113+ }
114+ . padding ( . bottom, 4 )
115+ . disabled ( acceptButtonDisabled)
116+ }
117+ . avoidKeyboard ( dismissKeyboardByTap: true )
118+ . transition ( . move( edge: . bottom) )
105119 }
106- } . transition ( . opacity)
107- . ignoresSafeArea ( )
120+ }
121+ . transition ( . opacity)
122+
123+ }
124+
125+ }
126+
127+ #if DEBUG
128+ struct PickerMenu_Previews : PreviewProvider {
129+ static var previews : some View {
130+
131+ let items = [
132+ PickerItem ( key: " Uk " , value: " Ukraine " ) ,
133+ PickerItem ( key: " Us " , value: " United States of America " ) ,
134+ PickerItem ( key: " En " , value: " England " )
135+ ]
136+
137+ return PickerMenu ( items: items,
138+ titleText: " Select country " ,
139+ router: BaseRouterMock ( ) ,
140+ selectedItem: items. first,
141+ selected: { _ in } )
108142 }
109143}
144+ #endif
0 commit comments