1- # DropdownTextField
1+ # DropdownTextField & MultiSelectionMenu – SwiftUI Components
22© 2025 Usama Javed. All rights reserved.
33
4+
45## Overview
5- DropdownTextField is a lightweight SwiftUI component that provides a searchable dropdown text field with customizable design and behavior .
6- It allows users to type, filter, and select from a list of options — similar to a searchable picker or auto-complete field .
6+ A lightweight and reusable set of SwiftUI components for building custom dropdown menus and multi-select menus with smooth UI, dynamic filtering, and tag-like selections .
7+ These components are designed for iOS 17+ and can be easily integrated into SwiftUI projects .
78
89### The library is designed to be:
910* Simple to integrate
1011* Easy to customize (colors, fonts, sizes, etc.)
1112* Flexible enough to fit any SwiftUI project
1213
13- ### Installation (Swift Package Manager)
14+
15+ ## 📌 Features
16+ ✅ DropdownTextField – Single selection dropdown with search and optional “Add New” entry.
17+ ✅ MultiSelectionMenu – Multi-select dropdown with tag-style chips and search support.
18+ ✅ Customizable colors, fonts, and corner radii.
19+ ✅ Keyboard-aware dropdown list.
20+ ✅ “No match” and “Add new” behaviors built-in.
21+ ✅ Written purely in SwiftUI.
22+
23+
24+
25+ ## 🚀 Installation
26+
27+ ### Swift Package Manager
14281 . In Xcode, open your project.
15292 . Go to File → Add Packages...
16303 . Enter the repository URL:
@@ -26,73 +40,124 @@ Then simply import it:
2640import DropdownTextField
2741```
2842
29- ### Usage Example
30- Here’s how to use SearchableMenu inside your SwiftUI view:
3143
3244
33- ``` swift
34- import SwiftUI
35- import DropdownTextField
36-
37- struct ContentView : View {
38- @State private var searchText = " "
39- @State private var isDropdownVisible = false
40- private let options = [" Apple" , " Mango" , " Banana" , " Cherry" , " Orange" ]
45+ ## 🧩 Usage
4146
47+ ### Example – DropdownTextField
48+
49+ ``` swift
50+ struct ExampleDropdown : View {
51+ @State private var searchText: String = " "
52+ @State private var isDropdownVisible: Bool = false
53+
54+ let options = [" Apple" , " Banana" , " Orange" , " Mango" ]
55+
4256 var body: some View {
43- VStack (spacing : 20 ){
44- Text (" Select a Fruit" )
45- .font (.headline )
46-
47- SearchableMenu (
48- searchText : $searchText,
49- isDropdownVisible : $isDropdownVisible,
50- options : options,
51- placeholder : " Search or select fruit"
52- ){
53- print (" Dropdown tapped" )
54- }
55- .padding (.horizontal , 16 )
57+ DropdownTextField (
58+ searchText : $searchText,
59+ isDropdownVisible : $isDropdownVisible,
60+ options : options,
61+ placeholder : " Select a fruit" ,
62+ addNew : true
63+ ){
64+ print (" Dropdown tapped" )
5665 }
5766 .padding ()
5867 }
5968}
6069```
6170
62-
63- ### Full Initializer
64- For customization, you can use all available parameters:
71+ ### Example – MultiSelectionMenu
6572
6673``` swift
67- SearchableMenu (
68- searchText : $searchText,
69- isDropdownVisible : $isDropdownVisible,
70- options : [" Swift" , " Kotlin" , " Dart" , " Java" ],
71- placeholder : " Select language" ,
72- addNew : true ,
73- textColor : .black ,
74- placeholderColor : .gray ,
75- accentColor : .blue ,
76- successColor : .green ,
77- destructiveColor : .red ,
78- borderColor : .gray ,
79- font : .system (size : 14 , weight : .medium ),
80- height : 48 ,
81- cornerRadius : 10 ,
82- dropdownIcon : Image (systemName : " chevron.down" ),
83- noMatchText : " No results found" ,
84- addNewTextFormat : " Add \" %@\" "
85- ){
86- print (" Dropdown opened" )
74+ struct ExampleMultiSelect : View {
75+ @State private var isDropdownVisible: Bool = false
76+ @State private var selectedValues: [String ] = []
77+
78+ let options = [" Swift" , " Kotlin" , " Java" , " Python" , " JavaScript" ]
79+
80+ var body: some View {
81+ MultiSelectionMenu (
82+ isDropdownVisible : $isDropdownVisible,
83+ selectedValues : $selectedValues,
84+ options : options,
85+ placeholder : " Select languages" ,
86+ maxOptionsCount : 5 ,
87+ addNew : true
88+ ){
89+ print (" Multi-selection tapped" )
90+ }
91+ .padding ()
92+ }
8793}
8894```
8995
90- ### Notes
91- ** onTap** is called when the dropdown field becomes active.
92- ** addNew** enables the option to add new items that don’t exist in the list.
93- The view automatically filters options based on the typed text.
9496
95- ## License
97+
98+ ## ⚙️ Parameters
99+
100+ ### DropdownTextField
101+
102+ | Parameter | Type | Default | Description |
103+ | ------------------- | --------------- | ------------------- | --------------------------------- |
104+ | ` searchText ` | Binding<String > | – | Text binding for search/selection |
105+ | ` isDropdownVisible ` | Binding<Bool > | – | Controls dropdown visibility |
106+ | ` options ` | [ String] | – | Dropdown options |
107+ | ` placeholder ` | String | – | Placeholder text |
108+ | ` addNew ` | Bool | ` false ` | Allow adding new custom text |
109+ | ` textColor ` | Color | ` .primary ` | Text color |
110+ | ` placeholderColor ` | Color | ` .gray ` | Placeholder color |
111+ | ` accentColor ` | Color | ` .blue ` | Highlight color |
112+ | ` successColor ` | Color | ` .green ` | Success state color |
113+ | ` destructiveColor ` | Color | ` .red ` | Not used but customizable |
114+ | ` borderColor ` | Color? | ` nil ` | Border color (optional) |
115+ | ` font ` | Font | ` .system(size: 16) ` | Font styling |
116+ | ` height ` | CGFloat | ` 40 ` | Field height |
117+ | ` cornerRadius ` | CGFloat | ` 8 ` | Rounded corners |
118+ | ` dropdownIcon ` | Image | ` chevron.down ` | Dropdown toggle icon |
119+ | ` noMatchText ` | String | ` "No match" ` | Shown when no match |
120+ | ` addNewTextFormat ` | String | ` "Add %@" ` | Format for new entry |
121+ | ` onTap ` | () -> Void | – | Callback on tap |
122+
123+
124+ ### MultiSelectionMenu
125+
126+ | Parameter | Type | Default | Description |
127+ | ------------------- | ----------------- | ------------------- | ------------------------------- |
128+ | ` isDropdownVisible ` | Binding<Bool > | – | Controls dropdown visibility |
129+ | ` selectedValues ` | Binding<[ String] > | – | Stores selected options |
130+ | ` options ` | [ String] | – | Dropdown options |
131+ | ` placeholder ` | String | – | Placeholder text |
132+ | ` maxOptionsCount ` | Int | ` 3 ` | Maximum allowed selections |
133+ | ` addNew ` | Bool | ` false ` | Allow adding new custom entries |
134+ | ` textColor ` | Color | ` .primary ` | Text color |
135+ | ` placeholderColor ` | Color | ` .gray ` | Placeholder color |
136+ | ` accentColor ` | Color | ` .blue ` | Highlight color |
137+ | ` successColor ` | Color | ` .green ` | Success state color |
138+ | ` borderColor ` | Color? | ` nil ` | Border color |
139+ | ` font ` | Font | ` .system(size: 16) ` | Font styling |
140+ | ` height ` | CGFloat | ` 40 ` | Field height |
141+ | ` cornerRadius ` | CGFloat | ` 8 ` | Rounded corners |
142+ | ` noMatchText ` | String | ` "No match" ` | Shown when no match |
143+ | ` addNewTextFormat ` | String | ` "Add %@" ` | Format for new entry |
144+ | ` onTap ` | () -> Void | – | Callback on tap |
145+
146+
147+
148+
149+ ## 🤝 Contributing
150+ Contributions are welcome!
151+ * Fork the repo
152+ * Create a new branch (feature/my-feature)
153+ * Commit your changes
154+ * Open a Pull Request
155+
156+ Please ensure all changes are consistent with SwiftUI’s declarative style and include example usage.
157+
158+
159+
160+ ## 📜 License
96161© 2025 Usama Javed. All rights reserved.
97162This Swift package is owned and maintained by Usama Javed.
98163All rights reserved. Redistribution without permission is prohibited.
0 commit comments