@@ -66,8 +66,19 @@ public struct PillOptions {
6666 /// Spacing applied horizontally between pills
6767 public var horizontalSpacing : CGFloat = 2
6868
69- /// Icon displayed in the pill when selected
70- public var selectedIcon : Image = Image ( systemName: " xmark " )
69+ /// Trailing icon displayed inside the pills
70+ public var trailingIcon : Image ? = nil
71+
72+ /// Leading icon displayed inside the pills
73+ public var leadingIcon : Image ? = nil
74+
75+ /// Whether leading icon should only be displayed if
76+ /// the element is selected or not
77+ public var leadingOnlyWhenSelected : Bool = false
78+
79+ /// Whether trailing icon should only be displayed if
80+ /// the element is selected or not
81+ public var trailingOnlyWhenSelected : Bool = false
7182}
7283
7384// MARK: - Main view
@@ -221,9 +232,27 @@ public extension PillPickerView {
221232 return view
222233 }
223234
224- func pillSelectedIcon( _ value: Image ) -> PillPickerView {
235+ func pillLeadingIcon( _ value: Image ) -> PillPickerView {
236+ var view = self
237+ view. options. leadingIcon = value
238+ return view
239+ }
240+
241+ func pillTrailingIcon( _ value: Image ) -> PillPickerView {
242+ var view = self
243+ view. options. trailingIcon = value
244+ return view
245+ }
246+
247+ func pillTrailingOnlySelected( _ value: Bool ) -> PillPickerView {
225248 var view = self
226- view. options. selectedIcon = value
249+ view. options. trailingOnlyWhenSelected = value
250+ return view
251+ }
252+
253+ func pillLeadingOnlySelected( _ value: Bool ) -> PillPickerView {
254+ var view = self
255+ view. options. leadingOnlyWhenSelected = value
227256 return view
228257 }
229258
@@ -252,23 +281,20 @@ struct PillView<T: Pill>: View {
252281 withAnimation ( options. animation) {
253282 if !isItemSelected( ) {
254283 selectedPills. append ( item)
284+ } else {
285+ selectedPills. removeAll ( where: { $0 == item } )
255286 }
256287 }
257288 } , label: {
258289 HStack {
290+ if !options. leadingOnlyWhenSelected || isItemSelected ( ) {
291+ leadingIcon
292+ }
259293 Text ( item. title)
260294 . font ( options. font)
261295 . foregroundColor ( pillForegroundColor)
262- if isItemSelected ( ) {
263- options. selectedIcon
264- . font ( options. font)
265- . foregroundColor ( pillForegroundColor)
266- . padding ( . leading, 5 )
267- . onTapGesture {
268- withAnimation ( options. animation) {
269- selectedPills. removeAll ( where: { $0 == item } )
270- }
271- }
296+ if !options. trailingOnlyWhenSelected || isItemSelected ( ) {
297+ trailingIcon
272298 }
273299 }
274300 . padding ( options. padding)
@@ -286,6 +312,20 @@ struct PillView<T: Pill>: View {
286312 . padding ( . vertical, 2.5 )
287313 }
288314
315+ var leadingIcon : some View {
316+ options. leadingIcon
317+ . font ( options. font)
318+ . foregroundColor ( pillForegroundColor)
319+ . padding ( . leading, 5 )
320+ }
321+
322+ var trailingIcon : some View {
323+ options. trailingIcon
324+ . font ( options. font)
325+ . foregroundColor ( pillForegroundColor)
326+ . padding ( . leading, 5 )
327+ }
328+
289329 // MARK: - Helper Functions
290330
291331 /// Checks if @Binding collection contains
@@ -367,11 +407,13 @@ struct StaticStack<T, V>: View where T: Pill, V: View {
367407 /// Current total height calculated
368408 @State private var totalHeight = CGFloat . zero
369409
410+ /// The calculateChunkSize function determines the optimal number
411+ /// of items per chunk based on the available width of the view.
370412 private func calculateChunkSize( geometry: GeometryProxy ) {
371413 let availableWidth = geometry. size. width
372414 let itemWidth : CGFloat = 100
373415
374- chunkSize = max ( Int ( availableWidth / ( itemWidth + options. horizontalSpacing) ) , 1 )
416+ chunkSize = max ( Int ( availableWidth / ( itemWidth + options. minWidth + options . horizontalSpacing) ) , 1 )
375417 }
376418
377419 // MARK: - Height Calculation
0 commit comments