1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
import SwiftUI
struct MullvadListNavigationItem: Hashable, Identifiable {
let id: UUID
let title: String
let state: String?
let detail: String?
let accessibilityIdentifier: AccessibilityIdentifier?
let didSelect: (() -> Void)?
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(title)
hasher.combine(state)
hasher.combine(detail)
}
static func == (lhs: MullvadListNavigationItem, rhs: MullvadListNavigationItem) -> Bool {
lhs.id == rhs.id
}
}
struct MullvadListNavigationItemView: View {
private let title: String
private let state: String?
private let detail: String?
private let accessibilityIdentifier: AccessibilityIdentifier?
private let didSelect: (() -> Void)?
@State private var isPressed = false
init(
item: MullvadListNavigationItem
) {
self.title = item.title
self.state = item.state.flatMap { $0.isEmpty ? nil : $0 }
self.detail = item.detail.flatMap { $0.isEmpty ? nil : $0 }
self.accessibilityIdentifier = item.accessibilityIdentifier
self.didSelect = item.didSelect
}
var body: some View {
Button {
didSelect?()
} label: {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text(title)
.foregroundStyle(Color(.Cell.titleTextColor))
.font(.mullvadSmallSemiBold)
.fixedSize(horizontal: false, vertical: true)
if let detail {
Text(detail)
.foregroundStyle(Color(.Cell.detailTextColor.withAlphaComponent(0.6)))
.font(.mullvadMiniSemiBold)
.fixedSize(horizontal: false, vertical: true)
}
}
Spacer()
if let state {
Text(state)
.foregroundStyle(Color(.Cell.titleTextColor.withAlphaComponent(0.6)))
.font(.mullvadTiny)
.fixedSize(horizontal: false, vertical: true)
}
Image(.iconChevron)
}
.padding(.horizontal, 16)
.padding(.vertical, 11)
.background(
isPressed
? Color.MullvadButton.primaryPressed
: Color.MullvadButton
.primary
)
}
.accessibilityIdentifier(accessibilityIdentifier?.asString ?? title)
.onButtonPressedChange { isPressed in
self.isPressed = isPressed
}
}
}
fileprivate extension View {
func onButtonPressedChange(_ onChange: @escaping (Bool) -> Void) -> some View {
buttonStyle(
MullvadListButtonStyle(onButtonPressedChange: onChange)
)
}
}
private struct MullvadListButtonStyle: ButtonStyle {
let onButtonPressedChange: (Bool) -> Void
func makeBody(configuration: Configuration) -> some View {
configuration.label
.onChange(of: configuration.isPressed) { newValue in
onButtonPressedChange(newValue)
}
}
}
#Preview {
Text("")
.sheet(isPresented: .constant(true)) {
MullvadList(
[
MullvadListNavigationItem(
id: UUID(),
title: "Test method",
state: "In use",
detail: "Very good method",
accessibilityIdentifier: nil,
didSelect: { print("selected") }
),
MullvadListNavigationItem(
id: UUID(),
title: "Test method2",
state: "In use",
detail: nil,
accessibilityIdentifier: nil,
didSelect: { print("selected") }
),
],
header: { EmptyView() },
footer: { EmptyView() },
content: { item in
MullvadListNavigationItemView(item: item)
}
)
}
}
|