Skip to content

Commit

Permalink
Merge branch 'main' into lmn-27/progress_bar-swfitui
Browse files Browse the repository at this point in the history
  • Loading branch information
frugoman authored Aug 1, 2023
2 parents f220de7 + 50bb858 commit 227d943
Show file tree
Hide file tree
Showing 43 changed files with 673 additions and 70 deletions.
208 changes: 208 additions & 0 deletions Backpack-SwiftUI/ChipGroup/Classes/BPKMultiSelectChipGroup.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2018 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import SwiftUI

/// A Group of chips that allows multiple chips to be selected at a time.
public struct BPKMultiSelectChipGroup: View {
private let chips: [ChipItem]
private let style: BPKChipStyle
private let type: ChipGroupType

public init(
chips: [ChipItem],
style: BPKChipStyle = .default,
type: ChipGroupType = .rail(stickyChip: nil)
) {
self.chips = chips
self.style = style
self.type = type
}

public var body: some View {
switch type {
case let .rail(stickyChip):
HStack(spacing: BPKSpacing.none) {
if let stickyChip {
BPKStickyChip(stickyChip: stickyChip, style: style)
Color(BPKColor.lineColor)
.frame(width: 1)
.frame(height: .xl)
.padding(.leading, .md)
}
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: .md) {
chipsListView
}
.if(stickyChip != nil, transform: {
$0.padding(.leading, .md)
})
.padding(.vertical, .sm)
}
}
case .wrap:
FlowStackView(spacing: .init(width: .md, height: .md)) {
chipsListView
}
}
}

private var chipsListView: some View {
ForEach(0..<chips.count, id: \.self) { index in
chip(for: chips[index])
}
}

@ViewBuilder
private func chip(for chip: ChipItem) -> some View {
switch chip.type {
case .option, .dropdown:
BPKChip(
chip.text,
icon: chip.icon,
selected: chip.selected,
style: style,
onClick: chip.onClick
)
case .dismiss:
BPKDismissableChip(
chip.text,
icon: chip.icon,
style: style,
onClick: chip.onClick
)
}
}
}

public extension BPKMultiSelectChipGroup.ChipItem {
enum ChipType {
case option, dropdown, dismiss
}
}

public extension BPKMultiSelectChipGroup {
enum ChipGroupType {
case rail(stickyChip: StickyChipItem?)
case wrap
}

struct StickyChipItem {
let accessibilityLabel: String
let icon: BPKIcon
let selected: Bool
let onClick: () -> Void

public init(
accessibilityLabel: String,
icon: BPKIcon,
selected: Bool,
onClick: @escaping () -> Void
) {
self.accessibilityLabel = accessibilityLabel
self.icon = icon
self.selected = selected
self.onClick = onClick
}
}

struct ChipItem {
let text: String
let icon: BPKIcon?
var type: ChipType
var selected: Bool
let onClick: () -> Void

public init(
text: String,
icon: BPKIcon? = nil,
type: ChipType = .option,
selected: Bool,
onClick: @escaping () -> Void
) {
self.text = text
self.icon = icon
self.type = type
self.selected = selected
self.onClick = onClick
}
}
}

struct BPKMultiSelectChipGroup_Previews: PreviewProvider {

static var previews: some View {
let chips: [BPKMultiSelectChipGroup.ChipItem] = [
.init(text: "Shenzhen", selected: false, onClick: {}),
.init(text: "London", selected: false, onClick: {}),
.init(text: "Edinburgh", selected: true, onClick: {}),
.init(text: "Manchester", selected: false, onClick: {}),
.init(text: "Belfast", selected: true, onClick: {}),
.init(text: "Glasgow", selected: false, onClick: {}),
.init(text: "Gurham", selected: false, onClick: {})
]
VStack {
BPKText("Rail", style: .heading3)
BPKMultiSelectChipGroup(
chips: chips,
type: .rail(stickyChip: BPKMultiSelectChipGroup.StickyChipItem(
accessibilityLabel: "Filters",
icon: .filter,
selected: false,
onClick: {}
))
)
.padding()
BPKMultiSelectChipGroup(
chips: chips,
style: .onDark
)
.padding()
.background(.surfaceContrastColor)
BPKMultiSelectChipGroup(
chips: chips,
style: .onImage
)
.padding()
.background(.statusSuccessSpotColor)
}
VStack {
BPKText("Wrap", style: .heading3)
BPKMultiSelectChipGroup(
chips: chips,
type: .wrap
)
.padding()
BPKMultiSelectChipGroup(
chips: chips,
style: .onDark,
type: .wrap
)
.padding()
.background(.surfaceContrastColor)

BPKMultiSelectChipGroup(
chips: chips,
style: .onImage,
type: .wrap
)
.padding()
.background(.statusSuccessSpotColor)
}
}
}
41 changes: 41 additions & 0 deletions Backpack-SwiftUI/ChipGroup/Classes/BPKStickyChip.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2018 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import SwiftUI

struct BPKStickyChip: View {
let stickyChip: BPKMultiSelectChipGroup.StickyChipItem
let style: BPKChipStyle

var body: some View {
Button(action: stickyChip.onClick) {
BPKIconView(stickyChip.icon)
.padding(.horizontal, .md)
}
.buttonStyle(
ChipButtonStyle(
style: style,
selected: stickyChip.selected,
disabled: false
)
)
.accessibilityAddTraits(stickyChip.selected ? [.isSelected] : [])
.sizeCategory(.large)
.accessibilityLabel(stickyChip.accessibilityLabel)
}
}
94 changes: 76 additions & 18 deletions Backpack-SwiftUI/ChipGroup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@

## Usage

Create ChipItems that used in the BPKSingleSelectChipGroup
### Single Select

Create ChipItems to be used in the group.

```swift
let chips: [BPKSingleSelectChipGroup.ChipItem] = [
.init(text: "Shenzhen", icon: .city),
Expand All @@ -32,55 +35,110 @@ let chips: [BPKSingleSelectChipGroup.ChipItem] = [
]
```

Single line group without default selected item:
```swift
BPKSingleSelectChipGroup(
chips: chips,
selectedIndex: .constant(nil)
) {
print("Chip item tapped")
}
```
#### Single line group

Single line group with specific selected item:
```swift
@State var selectedIndex: Int? = nil
BPKSingleSelectChipGroup(
chips: chips,
selectedIndex: .constant(2)
selectedIndex: selectedIndex,
type: .rail
) {
print("Chip item tapped")
}
```

Single line group on dark background:
#### Single line group on dark background:

```swift
BPKSingleSelectChipGroup(
chips: chips,
style: .onDark,
selectedIndex: .constant(2)
selectedIndex: selectedIndex
) {
print("Chip item tapped")
}
```

Single line group on an image background:
#### Single line group on an image background:

```swift
BPKSingleSelectChipGroup(
chips: chips,
style: .onImage,
selectedIndex: .constant(2)
selectedIndex: selectedIndex
) {
print("Chip item tapped")
}
```

Multiple lines of chips group
#### Multiple lines of chips group

```swift
BPKSingleSelectChipGroup(
chips: chips,
selectedIndex: .constant(2),
selectedIndex: selectedIndex,
type: .wrap
) {
print("Chip item tapped")
}
```

### Multiple Select

Create ChipItems to be used in the group.

```swift
@State var chips: [BPKMultiSelectChipGroup.ChipItem] = [
.init(text: "Shenzhen", icon: .city, selected: true),
.init(text: "London", icon: .city, selected: true),
.init(text: "Edinburgh", selected: false),
.init(text: "Manchester", selected: false),
.init(text: "Belfast", selected: false),
]
```

#### Single line group

```swift
BPKMultiSelectChipGroup(
chips: chips,
type: .rail(stickyChip: nil)
)
```

#### Single line group on dark background:

```swift
BPKMultiSelectChipGroup(
chips: chips,
style: .onDark
)
```

#### Single line group on an image background:

```swift
BPKMultiSelectChipGroup(
chips: chips,
style: .onImage
)
```

#### Single line group with a sticky chip:

```swift
BPKMultiSelectChipGroup(
chips: chips,
type: .rail(stickyChip: .init(accessibilityLabel: "Filters", icon: .filter, selected: false))
)
```

#### Multiple lines of chips group

```swift
BPKMultiSelectChipGroup(
chips: chips,
type: .wrap
)
```
Loading

0 comments on commit 227d943

Please sign in to comment.